56F8037 MSCAN QuickStartDemo problem

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

56F8037 MSCAN QuickStartDemo problem

671 Views
David_cz
Contributor I

Hi

I want to use 56F8037 for CAN communication between two 56F8037 EVM boards. If i download mscan_demo into flash it wont work correctly. This demo uses can buffer2 for transmitting variable lenght data through CAN bus (in main while loop), it would be after each transmittion go into interrupt service routine TXfull, but for first time it prepare data prepare buffer2 and sends but no interrupt wont come. For second time it stuck on :

 

while(!ioctl(MSCAN, MSCAN_SELECT_TXBUFF, MSCAN_TXBUFFER2))
;

 

and COP then reset mcu.

probably the buffer is still ful and no data were transmitted.

 

Complete demo code in attach.

 

THX

Labels (1)
0 Kudos
1 Reply

247 Views
David_cz
Contributor I

Hi again i have tried another setting of can bus with Quickstart no my code works perfectly in LoopBack mode but if i connect two 8037evm board together and load same codes to them program stops at line where is synchronization tested, if i disable this testing then i try to transmit data so no data are transmited and selected buffer2 is still full and interrupt TXempty is not executed.

 

So first problem is why node isnt synchronised with bus? And i think beacause of that transmitt buffer isnt depleted. But dont know why

 

THX

 

Code:

 

int main(void)
{
    static UWord16 i, txlen = 4;
    static UWord16* pd;

    // initialize SYS, COP and pins
    device_init();
   
    // enable MSCAN
    ioctl(MSCAN, MSCAN_DEVICE, MSCAN_ENABLE);

//******************************
//******************************   
    // enter soft-reset mode
    ioctl(MSCAN, MSCAN_SLEEP, MSCAN_ON);
    ioctl(MSCAN, MSCAN_SOFT_RESET, MSCAN_ENABLE);   
   
    // ...so we can continue configuration process here
    ioctl(MSCAN, MSCAN_SET_ACC_MODE, MSCAN_ACC_MODE_2X32);
    // open filter for standard IDs (let only lower byte matters, also IDE must be 0)
    ioctl(MSCAN, MSCAN_SET_ACC_MASKR_32_0, ~(MSCAN_Id2Idr(0xff) | MSCAN_IDR_IDE));
    ioctl(MSCAN, MSCAN_SET_ACC_IDR_32_0, MSCAN_Id2Idr(0x11));
    // open filter for extended IDs (let only lower 22 bits matters, also IDE must be 1)
    ioctl(MSCAN, MSCAN_SET_ACC_MASKR_32_1, ~(MSCAN_Id2Idr(0x803fffff) | MSCAN_IDR_IDE));
    ioctl(MSCAN, MSCAN_SET_ACC_IDR_32_1, MSCAN_Id2Idr(0x80333333) | MSCAN_IDR_IDE);
    // setting transfer speed and frames
    ioctl(MSCAN, MSCAN_SET_CLOCK_SOURCE, MSCAN_IPBUS);
    ioctl(MSCAN, MSCAN_SET_PRESCALER, 40);
    ioctl(MSCAN, MSCAN_SET_SJW, MSCAN_SJW_1);
    ioctl(MSCAN, MSCAN_SET_TSEG1, MSCAN_TSEG_8);
    ioctl(MSCAN, MSCAN_SET_TSEG2, MSCAN_TSEG_7);
    ioctl(MSCAN, MSCAN_SET_SAMPLING, MSCAN_3SAMPS_PER_BIT);
    // wake-up filter
    ioctl(MSCAN, MSCAN_WAKEUP_FILTER, MSCAN_DISABLE);
    // boot off recovery
    ioctl(MSCAN, MSCAN_MANUAL_BOFF_RECOVERY, MSCAN_DISABLE);
    // loopback mode
    ioctl(MSCAN, MSCAN_LOOPBACK_MODE, MSCAN_DISABLE);
    // listen only mode
    ioctl(MSCAN, MSCAN_LISTEN_ONLY_MODE, MSCAN_DISABLE);

    // exit soft-reset mode
    ioctl(MSCAN, MSCAN_SLEEP, MSCAN_OFF);
    ioctl(MSCAN, MSCAN_SOFT_RESET, MSCAN_DISABLE);
//******************************
//******************************

    // now can configure CAN
    ioctl(MSCAN, MSCAN_STOP_IN_WAIT, MSCAN_DISABLE);
    ioctl(MSCAN, MSCAN_TIMESTAMP_TIMER, MSCAN_DISABLE);
    ioctl(MSCAN, MSCAN_AUTO_WAKEUP, MSCAN_DISABLE);

    // now we can enable MSCAN interrupts (reset must be off)
    ioctl(MSCAN, MSCAN_ERINT_SET_RSTATE_MODE, MSCAN_STAT_ALL);
    ioctl(MSCAN, MSCAN_ERINT_SET_TSTATE_MODE, MSCAN_STAT_ALL);
    ioctl(MSCAN, MSCAN_ERINT_DISABLE, MSCAN_STATCHNG | MSCAN_OVERRUN | MSCAN_WAKEUP);

    // enable interrupts
    ioctl(INTC, INTC_INIT, NULL);
    archEnableInt();

    // switch to transmit buffer 2
    while(!ioctl(MSCAN, MSCAN_SELECT_TXBUFF, MSCAN_TXBUFFER2))
        ;

    // prepare Transmit buffer 2 to periodically transmit in the loop bellow
    ioctl(MSCAN_TB, MSCANMB_SET_ID, 0x333333 | MSCAN_ID_EXT);
   
    // data pointer
    pd = ioctl(MSCAN_TB, MSCANMB_GET_DATAPTR, NULL);
   
    // initialize data for periodical transmission
    // (each 16bit word contains a single data byte)
    pd[0] = 0x11;
    pd[1] = 0x22;
    pd[2] = 0x33;
    pd[3] = 0x44;
    pd[4] = 0x55;
    pd[5] = 0x66;
    pd[6] = 0x77;
    pd[7] = 0x88;

//    while(!ioctl(MSCAN, MSCAN_TEST_SYNCH, NULL))
//    ;

    // do forever  
    while(1)
    {
        /* disable RX interrupt which also touches the TX buffer selection */
        ioctl(MSCAN, MSCAN_ERINT_DISABLE, MSCAN_RXFULL);
       
        /* switch to transmit buffer 2 (also waits until this buffer is empty) */
        while(!ioctl(MSCAN, MSCAN_SELECT_TXBUFF, MSCAN_TXBUFFER2))
            ;
        ioctl(MSCAN_TB, MSCANMB_SET_LEN, txlen);

        /* re-enable receiver interrupt */
        ioctl(MSCAN, MSCAN_ERINT_ENABLE, MSCAN_RXFULL);
       
        /* transmit frame buffer 2 */
        ioctl(MSCAN, MSCAN_TRANSMIT, MSCAN_TXBUFFER2);     
        ioctl(MSCAN, MSCAN_TINT_ENABLE, MSCAN_TXBUFFER2);      
       
//        if(++txlen > 8)
//            txlen = 1;

        // wait a while
        for(i=0; i<50; i++)
        {
            ioctl(COP, COP_CLEAR_COUNTER, NULL);
            archDelay(0xffff);
        }
    }      
}

void MSCAN_ErrorISR(void)
{
#pragma interrupt saveall
    register UWord16 err = ioctl(MSCAN, MSCAN_READ_EINT_FLAGS, NULL);
    ioctl(MSCAN, MSCAN_CLEAR_EINT_FLAGS, err);
}

void MSCAN_WakeUpISR(void)
{
#pragma interrupt saveall
    ioctl(MSCAN, MSCAN_CLEAR_WINT_FLAG, NULL);
}

void MSCAN_RxFullISR(void)
{
#pragma interrupt saveall
    register UWord32 id = ioctl(MSCAN_RB, MSCANMB_GET_ID, NULL);
    register UWord16 len = ioctl(MSCAN_RB, MSCANMB_GET_LEN, NULL);
    register UWord16 isRTR = ioctl(MSCAN_RB, MSCANMB_GET_RTR, NULL);
    volatile UWord16 winf = ioctl(MSCAN, MSCAN_GET_WINNING_ACC_FILTER, NULL);

    ioctl(GPIO_LED_G2, GPIO_TOGGLE_PIN, LED_G2);

    // respond to non-RTR 0x11 frames only
    if(id == 0x11 && !isRTR)
    {
        /* use buffer 0 or 1 to send response back */
        UWord16 txbuff = ioctl(MSCAN, MSCAN_SELECT_TXBUFF, MSCAN_TXBUFFER0 | MSCAN_TXBUFFER1);
       
        /* have free buffer (either 0 or 1) */
        if(txbuff)
        {
            register UWord16* pdR = ioctl(MSCAN_RB, MSCANMB_GET_DATAPTR, NULL);
            register UWord16* pdT = ioctl(MSCAN_TB, MSCANMB_GET_DATAPTR, NULL);

            // copy data (don't need to check the len)
            pdT[0] = pdR[0];
            pdT[1] = pdR[1];
            pdT[2] = pdR[2];
            pdT[3] = pdR[3];
            pdT[4] = pdR[4];
            pdT[5] = pdR[5];
            pdT[6] = pdR[6];
            pdT[7] = pdR[7];

            // prepare ID (extended), LEN
            ioctl(MSCAN_TB, MSCANMB_SET_ID, 0x1111 | MSCAN_ID_EXT);
            ioctl(MSCAN_TB, MSCANMB_SET_LEN, len);

            // transmit buffer
            ioctl(MSCAN, MSCAN_TRANSMIT, txbuff);      
            ioctl(GPIO_LEDS, GPIO_TOGGLE_PIN, LED_R);
           
            // enable tx-finished interrupt
            ioctl(MSCAN, MSCAN_TINT_ENABLE, txbuff);       
        }
    }

    // LED responds to non-RTR ext 0x333333 frames only
    if(id == 0x80333333 && !isRTR)
    {
        ioctl(GPIO_LEDS, GPIO_TOGGLE_PIN, LED_G);
    }

    // clear interrupt flag
    ioctl(MSCAN, MSCAN_CLEAR_RINT_FLAG, NULL);
}

void MSCAN_TxRdyISR(void)
{
#pragma interrupt saveall
    /* what tx buffers are empty? */
    UWord16 tint = ioctl(MSCAN, MSCAN_READ_TINT_FLAGS, NULL);

    /* only consider buffers recently sent */
    tint &= ioctl(MSCAN, MSCAN_GET_ENABLED_TINT, NULL);
   
    if(tint & MSCAN_TXBUFFER2)
        ioctl(GPIO_LEDS, GPIO_TOGGLE_PIN, LED_Y2);
    if(tint & ~(MSCAN_TXBUFFER2))
        ioctl(GPIO_LEDS, GPIO_TOGGLE_PIN, LED_Y);
   
   
   
    /* disable interrupts handled */
    ioctl(MSCAN, MSCAN_TINT_DISABLE, tint);
}


/*
 *  Initialize SYS and all GPIO modules.
 */
void device_init(void)
{
    ioctl(SYS, SYS_INIT, NULL);
    ioctl(COP, COP_INIT, NULL);
   
    /* Note: This code is targeted to all 56F8xxx-based evaluation boards.
       So we need to check what GPIO instances are actually implemented */
    #ifdef GPIO_A
    ioctl(GPIO_A, GPIO_INIT, NULL);
    #endif
    #ifdef GPIO_B
    ioctl(GPIO_B, GPIO_INIT, NULL);
    #endif
    #ifdef GPIO_C
    ioctl(GPIO_C, GPIO_INIT, NULL);
    #endif
    #ifdef GPIO_D
    ioctl(GPIO_D, GPIO_INIT, NULL);
    #endif
    #ifdef GPIO_E
    ioctl(GPIO_E, GPIO_INIT, NULL);
    #endif
    #ifdef GPIO_F
    ioctl(GPIO_F, GPIO_INIT, NULL);
    #endif
}

0 Kudos