Howto detect speed of attached can-bus on lpc17xx

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Howto detect speed of attached can-bus on lpc17xx

3,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sipiyou on Tue May 26 23:46:31 MST 2015
Hi there,

I am wondering if it's possible to detect the speed of the attached can-bus to the lpc1788. If yes, can someone drop me a sample code ?
Couldn't find anything in lpc-xpresso sample base.

Thanks!
Labels (1)
Tags (1)
0 Kudos
24 Replies

2,325 Views
mark82
Contributor III

Well, after some other time spent on this issue I finally got the solution. The difference between LPC11C24 and LPC17XX is that the former has an internal loop-back from CAN TXD to CAN RXD that acks messages internally, triggering the reception interrupt, the latter don't. Technical support confirmed this difference.

So my actual solution is an external hardware loop-back and a standard transceiver with silent mode capability. My peripheral is always running in normal mode; when I need Listen Only mode I switch the transceiver to silent mode and activate the external loop. 

An alternative is to use a transceiver that already implements this loop-back HW internally. Usually it costs more. 

Hope this helps.

Regards,

Marco

0 Kudos

2,325 Views
mark82
Contributor III

Hi everyone.

 

I've been working on both LPC1788 and LPC1754 (with same CAN transceiver) for CAN autbauding feature. I'm encountering your same problems.

 

My setup is made up of only 2 device, one transmitting (later called Master) and LPCXXXX in listen-only. Same C code (common library). They both behave the same way: in both cases I can see the RS bit set, but not the RBS and I can see the right ID and data stored in the respective registers.

 

What my code does (or should do) is the following:

- Start device in silent mode and first baudrate;

- Catch any bus errors via IRQ (EI and BEI flags)

- Reinit peripheral with another baudrate if bus errors occur

- Repeat these steps till no error occur

- If IRQ handler receive a correct message, toggle from silent mode to normal mode

 

Well, this is obtained only if I have a third device already aknowledging the messages sent by the Master device.

 

Did you obtain any other progress?

 

Please notice that with the same procedure I can successfully find the baud rate with the LPC11C24 (same configuration, only 2 devices).

 

Regards and thank,

Marco

0 Kudos

2,325 Views
vicentegomez
NXP TechSupport
NXP TechSupport

Hi Marco

I will continue with your support on case 88348

regards

Vicente Gomez

0 Kudos

2,325 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by gpelgrim on Thu Dec 03 03:09:02 MST 2015
That is exactly the CAN configuration I have problems with too (1 listen-only device, 1 master). This what I see:
- The master sends messages in a very high interval (because the messages are not acknowledged).
- The Global Status Register of the listen-only device has the RS bit set (so it is receiving a message) but never the RBS bit (received a complete message).
- The receive registers holds the data of the message (I think it was Receive Identifier register with the COB-id and Receive Data register with the data).

I don't know what the step is between "receiving a message" and "complete message received".
0 Kudos

2,325 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sipiyou on Wed Dec 02 09:36:25 MST 2015
Sorry, I was supposed to write "listenmode".

Yes, this is also what I was expecting - controller will be silent to the outside world but will update it's internal registers so I can check the state.

But this is not the case on the 1788. I will double check this with another cpu. Are you doing something different than I am doing ? Could you please send me your code snippet ?

/edit: One more thing: I think the problem also occured in a minimum configured can-bus consisting out of 2 devices (this device + another).
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by gpelgrim on Wed Dec 02 03:03:36 MST 2015
With silence mode you mean "listen only mode"? I am very interested in the conversation you had with the FAE from NXP. I am using the LPC1756 and I see that the registers are updated in listen only mode. Why can't this mode be used for baudrate detection?

Edit:
This is what I find in the user manual for listen only mode:
"The controller gives no acknowledgment, even if a message is successfully
received. Messages cannot be sent, and the controller operates in “error
passive” mode. This mode is intended for software bit rate detection and
“hot plugging”.
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sipiyou on Wed Dec 02 01:45:36 MST 2015
If you enter silence mode the registers will not be updated, i.e: You can not use silence mode to get the baudrate detected. I had a long conversation with one FAE from NXP with no result.

From my point of view, this is a hardware bug inside the cpu. The registers simply do not output the errorstates to the application.

If you are in normal mode, the registers are updated properly so you can see if there're errors. But I had no time yet to test if this will cause problems in a real world application while the system is installed in a car.

Please let me know once you got a solution since I still got this one as a todo.
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by gpelgrim on Tue Dec 01 08:23:48 MST 2015
Can you confirm this works in case only a master is active on the CAN bus (but the messages are not acknowledged)?
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sipiyou on Thu Jun 25 01:33:15 MST 2015
@starblue: No I talked to R2D2. His first post was funny but the second one was useless specially after I told him that this is not a breadboard testing environment.

I already tried Listenmode but it is not working the way it should. Maybe I am doing something wrong but I do not see what. The LPC-manual tells that listenmode should be used for software
baudrate detection but there're no more hints in the manual what else needs to be considered. Attached you will find my short code which is based on lpcopen - except the d_printf_P ...

Only thing which just came into my mind is if the Acceptancefilter should be turned to "NormalMode" during ListenMode - but this is also something which is poorly described in the manual.

/edit: Tested also with CAN_SetAFMode (CAN_NORMAL); - but same issue. What is this mode for ?! I do not get any packets in normalmode in combination with this mode.

Once I init the can subsystem to ListenMode no interrupts are called (though from my understanding this should still be ?!) and GSR is not set, EWL = 0x60 (default reset-value). If I run
the system in Normal-mode, then the Error bit is set in GSR but it takes too long until the error bit is removed once I switch to the right can-bus. I guess this is because of the tx/rx-error count since this needs to go down to 0 first - but I can not run the system in NormalMode as this will also report problems on the bus.

For testing reasons I chose polling method to GSR in main-loop:

if (last_gsr != ( LPC_CAN1->GSR & (1<<6|1<<7))) {
    // GSR bit 6 = Error Status (1 = Error, 0 = ok)
    //     bit 7 = Error Bus (1= Error, 0 = Ok)
    last_gsr = LPC_CAN1->GSR & (1<<6|1<<7);
   
    d_printf_P ("SR: %x, %x %x\n", last_gsr, LPC_CAN1->SR, LPC_CAN1->EWL);
}

void myinit_can2 (uint32_t can1speed, uint32_t can2speed) {
    PINSEL_ConfigPin (0, 0, 1);
    PINSEL_ConfigPin (0, 1, 1);

    PINSEL_ConfigPin (2, 7, 1);
    PINSEL_ConfigPin (2, 8, 1);

    CAN_Init (CAN_ID_1, can1speed);
    CAN_Init (CAN_ID_2, can2speed);

    CAN_ModeConfig (CAN_ID_1, CAN_LISTENONLY_MODE, ENABLE);
    CAN_ModeConfig (CAN_ID_2, CAN_LISTENONLY_MODE, ENABLE);

    CAN_IRQCmd (CAN_ID_1, CANINT_RIE, ENABLE);
    CAN_IRQCmd (CAN_ID_2, CANINT_RIE, ENABLE);

    CAN_SetAFMode (CAN_ACC_BP);

    NVIC_EnableIRQ (CAN_IRQn);
}
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by starblue on Wed Jun 24 08:07:52 MST 2015

Quote: sipiyou
Did you read my previous post?


If you mean me, no, I didn't, as it was posted just a few minutes earlier.

In any case it is generally not a good idea to use thick wire with thick PVC insulation to fix signal connections on printed circuits.

And I would also suggest the try-all-baudrates approach, it appears simpler and more robust.
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by pnhnkvr on Wed Jun 24 03:09:29 MST 2015

Quote: R2D2
The easiest way to detect the CAN baudrate is to switch to Silent mode (to avoid error frames) and setup a loop to init the usual baudrates (100k, 125k, 250k, 500k, 1000k). Then just try to receive messages. If you can't receive messages and get CAN errors, switch to next baudrate. If you can receive messages, switch off Silent mode again :) 



Use this solution. Easy and somewhat elegant.
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sipiyou on Wed Jun 24 03:03:32 MST 2015
Did you read my previous post ?

This PCB is in series production. This means that I can not solder 2 wires on each pcb if the software gets updated. Due to this problem I need to find a solution for the current pcb which does not have the can-bus wired to the capture pins.
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Wed Jun 24 01:03:42 MST 2015

Quote: sipiyou
...I tried to use the GPIO int in combination with a match timer...



:quest:

... and GPS and 4-wheel drive  :O

What's wrong with capture?
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by starblue on Wed Jun 24 00:54:14 MST 2015

Quote: R2D2
I could sell you 2 of them for 100€  :D


Fortunately the correct magic wire for this kind of job is not that expensive (though not cheap either):
http://de.farnell.com/pro-power/rrp-g-105/einzelader-34m-1-0-15mm-kupfer/dp/146183
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sipiyou on Wed Jun 24 00:44:45 MST 2015
Sure, on prototypes this is useful but not for pcb which is in series production...  ;-)

In the meantime I tried to use the GPIO int in combination with a match timer but this will not result in any usable result. See code below:

void TIMER0_IRQHandler(void) {
    if (TIM_GetIntStatus(LPC_TIM0,TIM_MR0_INT) == SET) {
t1_counter++;
    }
}

Timer-Part:

    TIM_TIMERCFG_Type Timer0;
    TIM_MATCHCFG_Type MatchConfigStruct;
    uint32_t systick_reload_val = SysTick->CALIB;

    SysTick_Config(systick_reload_val / 10);

    Timer0.PrescaleOption = TIM_PRESCALE_USVAL;
    Timer0.PrescaleValue  = 1; // 1µs prescaler

    TIM_Init (LPC_TIM0, TIM_TIMER_MODE, &Timer0);

    LPC_TIM0->IR = 0xFFFFFFFF;
   
    MatchConfigStruct.MatchChannel = 0;
    MatchConfigStruct.IntOnMatch   = ENABLE;
    MatchConfigStruct.ResetOnMatch = ENABLE;
    MatchConfigStruct.StopOnMatch  = DISABLE;
    MatchConfigStruct.ExtMatchOutputType = 0;
    MatchConfigStruct.MatchValue   = 1; // time in µs
   
    TIM_ConfigMatch (LPC_TIM0, &MatchConfigStruct);

    TIM_Cmd (LPC_TIM0, ENABLE);
    NVIC_EnableIRQ (TIMER0_IRQn);

-----
#define INPUT00_PORT 0
#define INPUT00_PIN  0
#define INPUT00_MASK (1<<INPUT00_PIN)

volatile uint32_t counter_input00;
volatile uint16_t duration_input00;
volatile uint32_t last_int00;

GPIO-Int:

#define CHECK_PIN(n,pin)\
if ((last_int##n + 10) < t1_counter ) { \
    if (r & (pin) ) { \
if (counter_input##n == 0) { \
    counter_input##n = t1_counter; \
    r &= ~(pin);
} \
    } \
    \
    if (f & (pin)) { \
if (counter_input##n > 0) { \
    duration_input##n = t1_counter - counter_input##n; \
    counter_input##n = 0; \
} \
    } \
} \
if ( (r & (pin))  || (f & (pin))) { \
    last_int##n = t1_counter; \
}


void GPIO_IRQHandler (void) {
    uint32_t f,r;

    if (LPC_GPIOINT->IntStatus & 0x1) {
f = LPC_GPIOINT->IO0IntStatF;
r = LPC_GPIOINT->IO0IntStatR;

CHECK_PIN (00, INPUT00_MASK);

LPC_GPIOINT->IO0IntClr = INPUT00_MASK;
    }
}


code for init:

    CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCGPIO, ENABLE);

    LPC_GPIOINT->IO0IntEnR = LPC_GPIOINT->IO0IntEnF = INPUT00_MASK;
    NVIC_EnableIRQ (GPIO_IRQn);
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rocketdawg on Tue Jun 23 10:27:56 MST 2015
Be careful,
that is magic wire.
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue Jun 23 06:18:11 MST 2015

Quote: sipiyou
I can not bind the capture int onto these pins. Any idea ?



Our hardware design engineer has released a special tool for this purpose:

[img=1280x960]http://www.lpcware.com/system/files/Tools.jpg[/img]

It's the blue one...

I could sell you 2 of them for 100€  :D

0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sipiyou on Tue Jun 23 05:57:12 MST 2015
Got your point. But got another problem. I am using p0.0 and p0.1.

I can not bind the capture int onto these pins. Any idea ?!

Thanks :)
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue Jun 23 02:43:42 MST 2015

Quote: sipiyou
Using a capture timer I can only check if there's a bit transferred.



:quest:

Usually the smallest captured time is nearly 1 bit = 1 / baudrate  :O
0 Kudos

2,327 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sipiyou on Tue Jun 23 02:31:55 MST 2015
@R2D2: Sorry need to bug you...

I think you do not get my problem - if there is one...

Using a capture timer I can only check if there's a bit transferred. But as for the can-bus it's more complex. There's no clock signal which I can pickup and the transferred bits depend also on the utilization of the bus itself. Therefore I think it's quite hard to detect the speed by a timer. Therefore I asked for a sample.
0 Kudos