📄 can_drv.c
字号:
#include "common.h"
#include "can_drv.h"
//------------------------------------------------------------------------------
void can_clear_all_mob(void)
{
U8 mob_number;
///*
U8 data_index;
//*/
for (mob_number = 0; mob_number < NB_MOB; mob_number++)
{
CANPAGE = (mob_number << 4); //! Page index
Can_clear_mob(); //! All MOb Registers=0
///*
for (data_index = 0; data_index < NB_DATA_MAX; data_index++)
{
CANMSG = 0; //! MOb data FIFO
}
//*/
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
U8 can_get_mob_free(void)
{
U8 mob_number, page_saved;
page_saved = CANPAGE;
for (mob_number = 0; mob_number < NB_MOB; mob_number++)
{
Can_set_mob(mob_number);
if ((CANCDMOB & 0xC0) == 0x00) //! Disable configuration
{
CANPAGE = page_saved;
return (mob_number);
}
}
CANPAGE = page_saved;
return (NO_MOB);
}
//------------------------------------------------------------------------------
U8 can_get_mob_status(void)
{
U8 mob_status, canstmob_copy;
// Test if MOb ENABLE or DISABLE
if ((CANCDMOB & 0xC0) == 0x00) {return(MOB_DISABLE);}
canstmob_copy = CANSTMOB; // Copy for test integrity
// If MOb is ENABLE, test if MOb is COMPLETED
// - MOb Status = 0x20 then MOB_RX_COMPLETED
// - MOb Status = 0x40 then MOB_TX_COMPLETED
// - MOb Status = 0xA0 then MOB_RX_COMPLETED_DLCW
mob_status = canstmob_copy & ((1<<DLCW)|(1<<TXOK)|(1<<RXOK));
if (mob_status != 0) {return(mob_status);}
// If MOb is ENABLE & NOT_COMPLETED, test if MOb is in ERROR
// - MOb Status bit_0 = MOB_ACK_ERROR
// - MOb Status bit_1 = MOB_FORM_ERROR
// - MOb Status bit_2 = MOB_CRC_ERROR
// - MOb Status bit_3 = MOB_STUFF_ERROR
// - MOb Status bit_4 = MOB_BIT_ERROR
mob_status = canstmob_copy & ((1<<BERR)|(1<<SERR)|(1<<CERR)|(1<<FERR)|(1<<AERR));
if (mob_status != 0) {return(mob_status);}
// If CANSTMOB = 0 then MOB_NOT_COMPLETED
return(MOB_NOT_COMPLETED);
}
//------------------------------------------------------------------------------
void can_get_data(U8* p_can_message_data)
{
U8 data_index;
for (data_index = 0; data_index < (Can_get_dlc()); data_index++)
{
*(p_can_message_data + data_index) = CANMSG;
}
}
//------------------------------------------------------------------------------
U8 can_auto_baudrate (U8 mode)
{
U8 u8_temp0; //! Temporary variable
U8 brp, prs, ntq, phs1, phs2; //! Bit timing segment variables
U8 phs1_inc; //! Computing needed
U8 bt_not_found, wait_for_rx, evaluate; //! Keys for "while()" loops
U8 try_conf; //! Key for configurate CAN
U8 ovrtim_flag=0; //! Timer overflow count
U16 conf_index; //! Count of bit timing configuration tried
U8 bt_performed; //! Return flag
//! --- Default setting
phs1_inc = evaluate = 0;
bt_performed = 0;
conf_index = 0;
bt_not_found = 1;
//! --- Init segment variables with MIN values if mode=0
//! or init segment variables with CANBTx if mode=1
if (mode==0)
{
brp = BRP_MIN;
ntq = NTQ_MIN;
phs1 = PHS1_MIN;
phs2 = PHS2_MIN;
prs = ntq - ( phs1 + phs2 + 1 );
try_conf = 1; //! Try this configuration
wait_for_rx = 1; //! Enable "while (wait_for_rx ..." loop
}
else //! mode = 1
{
brp = Max ((((CANBT1 & BRP_MSK) >> 1) +1) , BRP_MIN );
prs = Max ((((CANBT2 & PRS_MSK) >> 1) +1) , PRS_MIN );
phs1 = Max ((((CANBT3 & PHS1_MSK) >> 1) +1) , PHS1_MIN);
phs2 = Max ((((CANBT3 & PHS2_MSK) >> 4) +1) , PHS2_MIN);
ntq = Max ((prs + phs1 + phs2 + 1) , NTQ_MIN);
phs1_inc = evaluate = 1; //! To enter in "while (evaluate ..." loop
try_conf = 0; //! Look for the next configuration
wait_for_rx = 0; //! Skip "while (wait_for_rx ..." loop
}
//! --- Clear all MOb's (CANMSG not cleared)
for (u8_temp0 = 0; u8_temp0 < NB_MOB; u8_temp0++)
{
Can_set_mob(u8_temp0); //! Page index
Can_clear_mob(); //! All MOb Registers = 0x00
}
while (bt_not_found == 1)
{
if (try_conf == 1)
{
Can_reset();
conf_index++;
ovrtim_flag=0;
//! --- CANBTx registers update (sjw = phs2/2, 3 sample points)
CANBT1 = ((brp-1) << BRP);
CANBT2 = (((phs2 >> 1)-1) << SJW) |((prs-1) << PRS);
CANBT3 = (((phs2-1) << PHS2) | ((phs1-1) << PHS1) | (1<<SMP));
//! --- Set CAN-Timer - Used for time-out
//! There are 641 (0x281) possible evaluations. The first one provides the faster
//! the faster bit timing, the last one gives the slower. It is necessary to
//! modulate the time-out versus bit timing (0x281>>3=0x50, matching an U8).
CANTCON = (U8)(conf_index >> 3);
//! --- MOb configuration
Can_set_mob(MOB_0); //! Use MOb-0
CANSTMOB = 0; //! Reset MOb status (undone by "Can_reset()")
CANCDMOB = (MOB_Rx_ENA << CONMOB); //! MOb 0 in receive mode
//! CAN controller configuration
CANGCON = (1<<LISTEN) | (1<<ENASTB);//! Enable CAN controller in "listen" mode
while ((CANGSTA & (1<<ENFG)) == 0); //! Wait for Enable OK
CANGIT = 0xFF; //! Reset General errors and OVRTIM flag
}
//! --- WAIT_FOR_RX LOOP:
//! ================
//! Try to perform a CAN message reception in "LISTEN" mode without error and
//! before a time_out done by CAN-Timer.
//! Else gives the hand to "EVALUATE LOOP" to have a new set of bit timing.
while (wait_for_rx == 1)
{
u8_temp0 = CANSTMOB;
//! --- RxOK received ?
if ((u8_temp0 & (1<<RXOK)) != 0)
{ //! --- It is the successful output of "can_auto_baudrate" function
wait_for_rx = 0; //! Out of "while (wait_for_rx ..." loop
evaluate = 0; //! Will skip "while (evaluate ..." loop
bt_not_found = 0; //! Out of "while (bt_not_found ..." loop
bt_performed = 1; //! Return flag = TRUE
DISABLE_MOB; //! Disable MOb-0
CANGCON = 0x00; //! Disable CAN controller & reset "listen" mode
while ((CANGSTA & (1<<ENFG)) != 0); //! Wait for Disable OK
}
//! --- Else stop if any errors
else
{
//! --- MOb error ?
if ((u8_temp0 & ((1<<BERR)|(1<<SERR)|(1<<CERR)|(1<<FERR)|(1<<AERR))) !=0)
{
evaluate = 1; //! Will enter in "while (evaluate ..." loop
wait_for_rx = 0; //! Out of "while (wait_for_rx ..." loop
}
u8_temp0 = CANGIT;
//! --- Time_out reached ?
if ((u8_temp0 & (1<<OVRTIM)) !=0 )
{
if (ovrtim_flag==0)
{
//! --- First Time_out
CANGIT |= (1<<OVRTIM); // Reset OVRTIM
ovrtim_flag++;
}
else
{
//! --- Second Time_out
CANGIT |= (1<<OVRTIM); // Reset OVRTIM
evaluate = 1; //! Will enter in "while (evaluate ..." loop
wait_for_rx = 0; //! Out of "while (wait_for_rx ..." loop
}
}
//! --- General error ?
if ((u8_temp0 & ((1<<SERG)|(1<<CERG)|(1<<FERG)|(1<<AERG))) !=0)
{
evaluate = 1; //! Will enter in "while (evaluate ..." loop
wait_for_rx = 0; //! Out of "while (wait_for_rx ..." loop
try_conf = 1; //! Try this configuration
}
}
} // while (wait_for_rx ...
//! --- EVALUATE LOOP:
//! =============
//! Compute a new bit timing configuration. First, Phase 1 is increased,
//! then Phase2=Phase1 and if Phase1>5, Phase1 can be equal to Phase2 or
//! Phase2+1. After this, the number of TQ is increased up to its high
//! limit and after it is the Prescaler. During the computing high (80%)
//! and low (75%) limits of sampling point location are tested. SJW and
//! the number of sampling points are not calculated in this loop.
while (evaluate == 1)
{
if (phs1_inc != 0) phs1++;
phs1_inc = 1;
// --- The following test takes into account the previous incrementation of phs1
if ((phs1 > PHS1_MAX) && (phs2 >= PHS2_MAX))
{
phs1 = PHS1_MIN;
phs2 = PHS2_MIN;
phs1_inc = 0;
if (ntq != NTQ_MAX) ntq++;
else
{
ntq = NTQ_MIN;
if (brp != BRP_MAX) brp++;
else
{
//! --- It is the failing of "can_auto_baudrate" function
evaluate = 0; //! Out of "while (evaluate ..." loop
bt_performed = 0; //! Return flag = FALSE
bt_not_found = 0; //! Out of "while (bt_not_found ..." loop
DISABLE_MOB; //! Disable MOb-0
CANGCON = 0x00; //! Disable CAN controller & reset "listen" mode
while ((CANGSTA & (1<<ENFG)) != 0); //! Wait for Disable OK
}
}
}
else // if (phs1 > PHS1_MAX ...
{
//! --- If psh1 > 5 then phs1 =phs2 or =phs2+1, else phs1=phs2
if (phs1>5)
{
if (phs1>(phs2+1)) phs1=(++phs2);
}
else
{
phs2=phs1;
}
prs = ntq - ( phs1 + phs2 + 1 );
//! --- Test PRS limits
if ((prs <= PRS_MAX) && (prs >= PRS_MIN))
{
//! --- Values accepted if 80% >= sampling point >= 75%
if (((phs2<<2) >= (1+prs+phs1)) && ((phs2+phs2+phs2) <= (1+prs+phs1)))
{
evaluate = 0; //! Out of "while (evaluate ..." loop &
wait_for_rx = 1; //! new "while (bt_not_found ..." loop
}
}
}
} // while (evaluate ...
} // while (bt_not_found ...
return (bt_performed);
}
//------------------------------------------------------------------------------
U8 can_fixed_baudrate(U8 mode)
{
Can_reset();
Can_conf_bt();
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -