⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 can.c

📁 Tried to make CAN logger on AT91sam7X-ek, but have no idea how to implement FATFs... -( I m just a
💻 C
📖 第 1 页 / 共 3 页
字号:
        CAN_InitMailboxRegisters( pCAN0Transfer );
    }
#endif
#if defined (AT91C_BASE_CAN0_MB8)
    for( i=0; i<8; i++ ) {
        pCAN0Transfer->can_number = 0;
        pCAN0Transfer->mailbox_number = i+8;
        pCAN0Transfer->mode_reg = AT91C_CAN_MOT_DIS;
        pCAN0Transfer->acceptance_mask_reg = 0;
        pCAN0Transfer->identifier = 0;
        pCAN0Transfer->data_low_reg = 0x00000000;
        pCAN0Transfer->data_high_reg = 0x00000000;
        pCAN0Transfer->control_reg = 0x00000000;
        CAN_InitMailboxRegisters( pCAN0Transfer );
    }
#endif

#if defined (AT91C_BASE_CAN1_MB0)
    if( pCAN1Transfer != NULL ) {
        CAN_ResetTransfer( pCAN1Transfer );
        for( i=0; i<8; i++ ) {
            pCAN1Transfer->can_number = 1;
            pCAN1Transfer->mailbox_number = i;
            pCAN1Transfer->mode_reg = AT91C_CAN_MOT_DIS;
            pCAN1Transfer->acceptance_mask_reg = 0;
            pCAN1Transfer->identifier = 0;
            pCAN1Transfer->data_low_reg = 0x00000000;
            pCAN1Transfer->data_high_reg = 0x00000000;
            pCAN1Transfer->control_reg = 0x00000000;
            CAN_InitMailboxRegisters( pCAN1Transfer );
        }
    }
#endif
#if defined (AT91C_BASE_CAN1_MB8)
    if( pCAN1Transfer != NULL ) {
        for( i=0; i<8; i++ ) {
            pCAN1Transfer->can_number = 1;
            pCAN1Transfer->mailbox_number = i+8;
            pCAN1Transfer->mode_reg = AT91C_CAN_MOT_DIS;
            pCAN1Transfer->acceptance_mask_reg = 0;
            pCAN1Transfer->identifier = 0;
            pCAN1Transfer->data_low_reg = 0x00000000;
            pCAN1Transfer->data_high_reg = 0x00000000;
            pCAN1Transfer->control_reg = 0x00000000;
            CAN_InitMailboxRegisters( pCAN1Transfer );
        }
    }
#endif

}

//------------------------------------------------------------------------------
/// CAN reset Transfer descriptor
/// \param pTransfer can transfer structure
//------------------------------------------------------------------------------
void CAN_ResetTransfer( CanTransfer *pTransfer )
{
    pTransfer->state = CAN_IDLE;
    pTransfer->can_number = 0;
    pTransfer->mailbox_number = 0;
    pTransfer->test_can = 0;
    pTransfer->mode_reg = 0;
    pTransfer->acceptance_mask_reg = 0;
    pTransfer->identifier = 0;
    pTransfer->data_low_reg = 0;
    pTransfer->data_high_reg = 0;
    pTransfer->control_reg = 0;
    pTransfer->mailbox_in_use = 0;
    pTransfer->size = 0;
}

//------------------------------------------------------------------------------
/// Wait for CAN synchronisation
/// \return return 1 for good initialisation, otherwise return 0
//------------------------------------------------------------------------------
static unsigned char CAN_Synchronisation( void )
{
    unsigned int tick=0;

    TRACE_INFO("CAN_Synchronisation\n\r");

    pCAN0Transfer->test_can = AT91C_TEST_NOK;
#ifdef AT91C_BASE_CAN1
    if( pCAN1Transfer != NULL ) {
        pCAN1Transfer->test_can = AT91C_TEST_NOK;
    }
#endif
    // Enable CAN and Wait for WakeUp Interrupt
    AT91C_BASE_CAN0->CAN_IER = AT91C_CAN_WAKEUP;
    // CAN Controller Enable
    AT91C_BASE_CAN0->CAN_MR = AT91C_CAN_CANEN;
    // Enable Autobaud/Listen mode
    // dangerous, CAN not answer in this mode

     while( (pCAN0Transfer->test_can != AT91C_TEST_OK)
         && (tick < AT91C_CAN_TIMEOUT) ) {
        tick++;
    }
    if (tick == AT91C_CAN_TIMEOUT) {
        TRACE_ERROR("CAN0 Initialisations FAILED\n\r");
        return 0;
    } else {
        TRACE_INFO("CAN0 Initialisations Completed\n\r");
    }

#if defined AT91C_BASE_CAN1
    if( pCAN1Transfer != NULL ) {
        AT91C_BASE_CAN1->CAN_IER = AT91C_CAN_WAKEUP;
        // CAN Controller Enable
        AT91C_BASE_CAN1->CAN_MR = AT91C_CAN_CANEN;

        tick = 0;
        // Wait for WAKEUP flag raising <=> 11-recessive-bit were scanned by the transceiver
        while( ((pCAN1Transfer->test_can != AT91C_TEST_OK)) 
            && (tick < AT91C_CAN_TIMEOUT) ) {
            tick++;
        }

        if (tick == AT91C_CAN_TIMEOUT) {
            TRACE_ERROR("CAN1 Initialisations FAILED\n\r");
            return 0;
        } else {
            TRACE_INFO("CAN1 Initialisations Completed\n\r");
        }
    }
#endif
    return 1;
}

//------------------------------------------------------------------------------
/// Write a CAN transfer
/// \param pTransfer can transfer structure
/// \return return CAN_STATUS_SUCCESS if command passed, otherwise 
///         return CAN_STATUS_LOCKED
//------------------------------------------------------------------------------
unsigned char CAN_Write( CanTransfer *pTransfer )
{
    AT91PS_CAN base_can;

    if (pTransfer->state == CAN_RECEIVING)  {
        pTransfer->state = CAN_IDLE;
    }

    if (pTransfer->state != CAN_IDLE)  {
        return CAN_STATUS_LOCKED;
    }

    TRACE_DEBUG("CAN_Write\n\r");
    pTransfer->state = CAN_SENDING;
    if( pTransfer->can_number == 0 ) {
        base_can = AT91C_BASE_CAN0;
    }
#ifdef AT91C_BASE_CAN1
    else {
        base_can = AT91C_BASE_CAN1;
    }
#endif
    base_can->CAN_TCR = pTransfer->mailbox_in_use;
    base_can->CAN_IER = pTransfer->mailbox_in_use;

    return CAN_STATUS_SUCCESS;

}


//------------------------------------------------------------------------------
/// Read a CAN transfer
/// \param pTransfer can transfer structure
/// \return return CAN_STATUS_SUCCESS if command passed, otherwise 
///         return CAN_STATUS_LOCKED
//------------------------------------------------------------------------------
unsigned char CAN_Read( CanTransfer *pTransfer )
{
    AT91PS_CAN base_can;

    if (pTransfer->state != CAN_IDLE)  {
        return CAN_STATUS_LOCKED;
    }

    TRACE_DEBUG("CAN_Read\n\r");
    pTransfer->state = CAN_RECEIVING;


    if( pTransfer->can_number == 0 ) {
        base_can = AT91C_BASE_CAN0;
    }
#ifdef AT91C_BASE_CAN1
    else {
        base_can = AT91C_BASE_CAN1;
    }
#endif
    // enable interrupt
    base_can->CAN_IER = pTransfer->mailbox_in_use;

    return CAN_STATUS_SUCCESS;
}

//------------------------------------------------------------------------------
/// Test if CAN is in IDLE state
/// \param pTransfer can transfer structure
/// \return return 0 if CAN is in IDLE, otherwise return 1
//------------------------------------------------------------------------------
unsigned char CAN_IsInIdle( CanTransfer *pTransfer )
{
  return( pTransfer->state != CAN_IDLE );
}

//------------------------------------------------------------------------------
/// Basic CAN test without Interrupt
//------------------------------------------------------------------------------
void CAN_BasicTestSuiteWithoutInterrupt(void)
{
#if defined AT91C_BASE_CAN1
    unsigned int status;
    unsigned int tick=0;

    TRACE_INFO("Without Interrupt ");
    TRACE_INFO("CAN0 Mailbox 0 transmitting to CAN1 Mailbox 0\n\r");
    // Init CAN0 Mailbox 0, transmit
    CAN_ResetTransfer( pCAN0Transfer );
    pCAN0Transfer->can_number = 0;
    pCAN0Transfer->mailbox_number = 0;
    pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR;
    pCAN0Transfer->acceptance_mask_reg = 0x00000000;
    pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x07<<18);
    pCAN0Transfer->data_low_reg = 0x11223344;
    pCAN0Transfer->data_high_reg = 0x01234567;
    pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16));
    CAN_InitMailboxRegisters( pCAN0Transfer );

    // Init CAN1 Mailbox 0, receive, 
    CAN_ResetTransfer( pCAN1Transfer );
    pCAN1Transfer->can_number = 1;
    pCAN1Transfer->mailbox_number = 0;
    pCAN1Transfer->mode_reg = AT91C_CAN_MOT_RX;
    pCAN1Transfer->acceptance_mask_reg = AT91C_CAN_MIDvA | AT91C_CAN_MIDvB;
    pCAN1Transfer->identifier = AT91C_CAN_MIDvA & (0x07<<18);
    pCAN1Transfer->data_low_reg = 0x00000000;
    pCAN1Transfer->data_high_reg = 0x00000000;
    pCAN1Transfer->control_reg = 0x00000000;
    CAN_InitMailboxRegisters( pCAN1Transfer );

    // Transfer Request for Mailbox 0
    AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB0;

    tick = 0;
    do {
        // CAN Message Status Register
        status = AT91C_BASE_CAN0_MB0->CAN_MB_MSR;
    }
    while( !(status & AT91C_CAN_MRDY) && (++tick < AT91C_CAN_TIMEOUT) );

    if (tick == AT91C_CAN_TIMEOUT) {
        TRACE_ERROR("Test FAILED\n\r");
    } 
    else {
        TRACE_DEBUG("Transfer completed: CAN1 Mailbox 0 MRDY flag has raised\n\r");
        if( AT91C_BASE_CAN0_MB0->CAN_MB_MDL != AT91C_BASE_CAN1_MB0->CAN_MB_MDL ) {
            TRACE_ERROR("Data Corrupted\n\r");
        }
        else if( AT91C_BASE_CAN0_MB0->CAN_MB_MDH != AT91C_BASE_CAN1_MB0->CAN_MB_MDH ) {
            TRACE_ERROR("Data Corrupted\n\r");
        }
        else {
            TRACE_INFO("Test passed\n\r");
        }
    }

    CAN_ResetAllMailbox();

    TRACE_INFO("Without Interrupt ");
    TRACE_INFO("CAN0 Mailboxes 1 & 2 transmitting to CAN1 Mailbox 15\n\r");
    // Init CAN0 Mailbox 1, transmit
    CAN_ResetTransfer( pCAN0Transfer );
    pCAN0Transfer->can_number = 0;
    pCAN0Transfer->mailbox_number = 1;
    pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR;
    pCAN0Transfer->acceptance_mask_reg = 0x00000000;
    pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x09<<18);      // ID 9
    pCAN0Transfer->data_low_reg = 0xAABBCCDD;
    pCAN0Transfer->data_high_reg = 0xCAFEDECA;
    pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code
    CAN_InitMailboxRegisters( pCAN0Transfer );

    // Init CAN0 Mailbox 2, transmit
    pCAN0Transfer->can_number = 0;
    pCAN0Transfer->mailbox_number = 2;
    pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | (AT91C_CAN_PRIOR-(1<<16));
    pCAN0Transfer->acceptance_mask_reg = 0x00000000;
    pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x0A<<18);      // ID 10
    pCAN0Transfer->data_low_reg = 0x55667788;
    pCAN0Transfer->data_high_reg = 0x99AABBCC;
    pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code
    CAN_InitMailboxRegisters( pCAN0Transfer );

    // Init CAN1 Mailbox 15, reception with overwrite
    CAN_ResetTransfer( pCAN1Transfer );
    pCAN1Transfer->can_number = 1;
    pCAN1Transfer->mailbox_number = 15;
    pCAN1Transfer->mode_reg = AT91C_CAN_MOT_RXOVERWRITE;
    pCAN1Transfer->acceptance_mask_reg = 0;
    pCAN1Transfer->identifier = 0x0;
    pCAN1Transfer->data_low_reg = 0x00000000;
    pCAN1Transfer->data_high_reg = 0x00000000;
    pCAN1Transfer->control_reg = 0x00000000;
    CAN_InitMailboxRegisters( pCAN1Transfer );

    // Ask Transmissions on Mailbox 1 & 2 --> AT91C_CAN_MRDY & AT91C_CAN_MMI raises for Mailbox 15 CAN_MB_SR
    AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB1 | AT91C_CAN_MB2;
    
    // Wait for Last Transmit Mailbox
    tick = 0;
    do  {
        status = AT91C_BASE_CAN1_MB15->CAN_MB_MSR;
    }
    while( !(status & AT91C_CAN_MMI) && (++tick < AT91C_CAN_TIMEOUT) );

    if (tick == AT91C_CAN_TIMEOUT) {
    }
    else {
        TRACE_DEBUG("Transfer completed: CAN1 Mailbox 15 MRDY and MMI flags have raised\n\r");
        if( AT91C_BASE_CAN0_MB1->CAN_MB_MDL != AT91C_BASE_CAN1_MB15->CAN_MB_MDL ) {
            TRACE_ERROR("Data Corrupted\n\r");
        }
        else if( AT91C_BASE_CAN0_MB1->CAN_MB_MDH != AT91C_BASE_CAN1_MB15->CAN_MB_MDH ) {
            TRACE_ERROR("Data Corrupted\n\r");
        }
        else {
            TRACE_INFO("Test passed\n\r");
        }
    }

    CAN_ResetAllMailbox();
    TRACE_INFO("Without Interrupt ");
    TRACE_INFO("CAN0 Mailboxes 1 & 2 transmitting to CAN1 Mailbox 15\n\r");
    // Init CAN0 Mailbox 1, transmit
    CAN_ResetTransfer( pCAN0Transfer );
    pCAN0Transfer->can_number = 0;
    pCAN0Transfer->mailbox_number = 1;
    pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR;
    pCAN0Transfer->acceptance_mask_reg = 0x00000000;
    pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x09<<18);      // ID 9
    pCAN0Transfer->data_low_reg = 0xAABBCCDD;
    pCAN0Transfer->data_high_reg = 0xCAFEDECA;
    pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code
    CAN_InitMailboxRegisters( pCAN0Transfer );

    // Init CAN0 Mailbox 2, transmit
    pCAN0Transfer->can_number = 0;
    pCAN0Transfer->mailbox_number = 2;
    pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | (AT91C_CAN_PRIOR-(1<<16));
    pCAN0Transfer->acceptance_mask_reg = 0x00000000;
    pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x0A<<18);      // ID 10
    pCAN0Transfer->data_low_reg = 0x55667788;
    pCAN0Transfer->data_high_reg = 0x99AABBCC;
    pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -