CAN_BaudRateCalculate
Default mainpageat91libperipheralscanCAN_BaudRateCalculate
Description Source Call Graph
Start Line: 865
unsigned char CAN_BaudRateCalculate(AT91PS_CAN base_CAN, unsigned int baudrate)
{
    unsigned int BRP;
    unsigned int PROPAG;
    unsigned int PHASE1;
    unsigned int PHASE2;
    unsigned int SJW;
    unsigned int t1t2;
    unsigned char TimeQuanta;

    base_CAN->CAN_BR = 0;

    if( baudrate == 1000) {
        TimeQuanta = 8;
    }
    else {
        TimeQuanta = 16;
    }

    BRP = (BOARD_MCK / (baudrate*1000*TimeQuanta))-1;
    //TRACE_DEBUG("BRP = 0x%X\n\r", BRP);
    // timing Delay:
    // Delay Bus Driver: 50 ns
    // Delay Receiver:   30 ns
    // Delay Bus Line (20m):  110 ns
    if( (TimeQuanta*baudrate*2*(50+30+110)/1000000) >= 1) {
        PROPAG = (TimeQuanta*baudrate*2*(50+30+110)/1000000)-1;
    }
    else {
        PROPAG = 0;
    }
    //TRACE_DEBUG("PROPAG = 0x%X\n\r", PROPAG);

    t1t2 = TimeQuanta-1-(PROPAG+1);
    //TRACE_DEBUG("t1t2 = 0x%X\n\r", t1t2);

    if( (t1t2 & 0x01) == 0x01 ) {
        // ODD
        //TRACE_DEBUG("ODD\n\r");
        PHASE1 = ((t1t2-1)/2)-1;
        PHASE2 = PHASE1+1;
    }
    else {
        // EVEN
        //TRACE_DEBUG("EVEN\n\r");
        PHASE1 = (t1t2/2)-1;
        PHASE2 = PHASE1;
    }
    //TRACE_DEBUG("PHASE1 = 0x%X\n\r", PHASE1);
    //TRACE_DEBUG("PHASE2 = 0x%X\n\r", PHASE2);

    if( 1 > (4/(PHASE1+1)) ) {
        //TRACE_DEBUG("4*Tcsc\n\r");
        SJW = 3;
    }
    else {
        //TRACE_DEBUG("Tphs1\n\r");
        SJW = PHASE1;
    }
    //TRACE_DEBUG("SJW = 0x%X\n\r", SJW);
    // Verif
    if( BRP == 0 ) {
        TRACE_DEBUG("BRP = 0 is not authorized\n\r");
        return 0;
    }

    if( (PROPAG + PHASE1 + PHASE2) != (TimeQuanta-4) ) {
        TRACE_DEBUG("Pb (PROPAG + PHASE1 + PHASE2) = %d\n\r", PROPAG + PHASE1 + PHASE2);
        TRACE_DEBUG("with TimeQuanta-4 = %d\n\r", TimeQuanta-4);
        return 0;
    }
    base_CAN->CAN_BR = (AT91C_CAN_PHASE2 & (PHASE2 <<  0))
                     + (AT91C_CAN_PHASE1 & (PHASE1 <<  4))
                     + (AT91C_CAN_PROPAG & (PROPAG <<  8))
                     + (AT91C_CAN_SYNC   & (SJW << 12))
                     + (AT91C_CAN_BRP    & (BRP << 16))
                     + (AT91C_CAN_SMP    & (0 << 24));
    return 1;

}