mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Issue: LPC11CXX target can_frequency() doesn't configure bit timing properly (Closed: Fixed)

As per section 16.6.1.4 (pg 238) of the LPC11Cxx user manual (http://www.nxp.com/documents/user_manual/UM10398.pdf), both the CCE (bit timing) and INIT (general CAN config) bits must be set in the CANCTRL register to modify the bit timing.

The current implementation only sets the CCE bit in can_frequency, so calls to can_frequency only succeed if the INIT bit was already set, which is only true when called from can_init.

Adding code to set/clear the INIT bit (optionally remembering the initial value) in can_frequency solves this problem and makes it possible to set the frequency with CAN::frequency.

Tangent: the bit timing calculation code in can_speed effectively sets a minimum baud rate divider of 2 because of the placement of the increment on BRP, which might not be desirable.

3 comments:

13 May 2014

Hello,

is this how you proposed to fix it?

int can_frequency(can_t *obj, int f) {
    int btr = can_speed(SystemCoreClock, (unsigned int)f, 1);
    int clkdiv = (btr >> 16) & 0x0F;
    btr = btr & 0xFFFF;
    
    if (btr > 0) {
        uint32_t cntl_init = LPC_CAN->CNTL & CANCNTL_INIT;
        // Set the bit clock
        LPC_CAN->CNTL |= CANCNTL_CCE | CANCNTL_INIT;
        LPC_CAN->CLKDIV = clkdiv;
        LPC_CAN->BT = btr;
        LPC_CAN->BRPE = 0x0000;
        LPC_CAN->CNTL &= ~(CANCNTL_CCE & CANCNTL_INIT);
        LPC_CAN->CNTL |= cntl_init << 0;
        return 1;
    }
    return 0;
}
16 May 2014

Hi Martin,

On line 13, the statement

LPC_CAN->CNTL &= ~(CANCNTL_CCE & CANCNTL_INIT);

Will actually do nothing, since (CANCNTL_CCE & CANCNTL_INIT) evaluates to 0, and taking the bitwise inverse of that results in 0xFFFFFFFF, which does nothing when anded with the register.

Instead, it should be

LPC_CAN->CNTL &= ~(CANCNTL_CCE | CANCNTL_INIT);

Other than that, your proposed code has the right logic.

On line 14, the bitshift by 0 seems unnecessary, but doesn't affect the correctness.

21 May 2014

Thanks for an answer, going to fix it and close this issue.

I placed there logical and by mistake :)