Ten driver ma asi 1500 radek, tady jsou ty dulezite pasaze.
Jinak komentare at uz ceske nebo anglicke jsou plne preklepu....
Nektere promenne jsou znovupouzite pro jiny ucel, nez vyplyva z jejich nazvu, vetsinou kvuli rychlosti, jsou totiz alokovany v registrech ne na stacku.
Nastavuje se to tady:
Kód: Vybrat vše
sregtmp=SREG;
#asm("cli");
txmob_free_list &= itmp; /*negative mask here*/
/*Put MSG into HW*/
/*select MOb page*/
CAN_SET_R_CANPAGE(ctmp);
#warning remove the test
if(!ctmp) /*test only*/
{
ctmp++;
ctmp--;
}
/*write data*/
CAN_SET_R_DATAIDX_RESET_AINC;
ctmp=msg->dlc;
ctmp&=0x0f;
//CANCDMOB = ctmp; /*prepare dlc to CANCDMOB register; mob temporarily set to disabled*/
if(~itmp & rtrautomob_list) /*check if the mob has autoreply nature*/
{
/*prepare RPLV flag, should not matter that data aren't ready yet as mob isn't switched to rx*/
CANCDMOB = CAN_CANCDMOB_RPLV_MASK | (CANCDMOB & ~(CAN_MOBCNF_FLAG_MODE_MASK | CAN_CANCDMOB_IDE_MASK) ); /*set to disabled, keep original dlc and ide, ext cleared*/
}
else CANCDMOB = ctmp; /*prepare dlc to CANCDMOB register; mob temporarily set to disabled, rplv and ext cleared*/
#if CAN_RTR_MODE == CAN_RTR_MODE_RTR_NORMAL
if(! (msg->flags & CAN_MSG_FLAG_RTR) ) /* this is no RTR message, data copying needed*/
{
#endif
itmp = (unsigned int) (msg->data);
while(ctmp)
{
CANMSG=*(char*)itmp;
itmp++;
ctmp--;
}
#if CAN_RTR_MODE == CAN_RTR_MODE_RTR_NORMAL
}
else CANIDT4 = CAN_CANIDT_RTR_MASK;
#else
CANIDT4=0;
#endif
if(!(CANCDMOB & CAN_CANCDMOB_RPLV_MASK) ) /*indicates !(autoreply mob with new data to be sent)*/
{
if(msg->flags & CAN_MSG_FLAG_EID)
{
itmp=msg->id;
ctmp=itmp>>8;
itmp<<=3;
CANIDT4|=(char)itmp; /*low of shifted id; RTR kept according flag; RB0, RB1 kept 0*/
CANIDT3=itmp>>8; /*high of shifted id*/
itmp=msg->ide;
itmp<<=3;
ctmp>>=5; /*holds the carry bits between id and ide during the shift*/
CANIDT2=(unsigned char)itmp | ctmp;
CANIDT1= itmp>>8;
//CAN_SET_CUR_MOB_TO_TXE;
CAN_SET_CUR_MOB_EXT_FLAG_ONLY;
}
else
{
itmp=msg->id;
itmp <<=5;
//CANIDT4=0; treaten in RTR section, see above
CANIDT2= itmp;
CANIDT1= itmp>>8;
//CAN_SET_CUR_MOB_TO_TX;
//CAN_CLEAR_CUR_MOB_EXT_FLAG_ONLY; not needed, already cleared
}
}
K odeslani dochazi zde (v konkretnim pripade je tahle cast v ISR):
Ve vhodny okamzik se tu do pripravenenho MOBu zapise vysilaci pokyn.
Cele je to kvuli tomu, abych mnozinu vysilacich MOBu transformoval z prioritniho odesilani (ktere je mi k nicemu) na FIFO chovani.
Kód: Vybrat vše
if(CANCDMOB & CAN_CANCDMOB_RPLV_MASK) /*is it rtr autoreply?*/
{ /*yes - activate RX*/
CAN_SET_CUR_MOB_TO_RX;
}
else /* no*/
{
/* initiate transmission (if conditions are met)*/
itmp = ~(txmob_free_list | ~txmob_list | txmob_txcmd_list); /* mask of mobs with are ready for tx command*/
dptr = (unsigned char*)CAN_MOB_LAST_MASK; /*right moving mask, 0x4000 15mobs for at90CAN128/64/32, starting on bit 14*/
local_canpage_backup = CANPAGE;
tmpc = (local_canpage_backup & 0x0f) | ((CAN_NUMBER_OF_MOBS-1)<<4); // 0xe0;
while( (unsigned int)dptr & ~txmob_txcmd_list)
{
if(itmp & (unsigned int)dptr) /* ready to send mob found*/
{
CANPAGE = tmpc; /*no R-M-W operation here*/
CAN_SET_CUR_MOB_TO_TX;
txmob_txcmd_list |= (unsigned int)dptr;
}
dptr = (unsigned char*)((unsigned int)dptr>>1);
tmpc -= 0x10; /*doesn't affect low nibble*/
}
CANPAGE = local_canpage_backup;
}
}