/**
* \file RDMOD16X.C
*
* \author Axel Wolf, SCI Cupertino
* \author Dr. Jens Barrenscheen, HL MC PD, Munich
* \author Hubert Piontek, University of Ulm
*
* Routine for reading data from the last message object
*
* Most of this is based von the Infineon/Siemens Application Note AP2922.
* Some additions made at University of Ulm, February 2003.
*
* This CAN driver is mainly meant to be used by the publisher/subscriber
* library developed at the University of Ulm, 1999-2003.
*/
/*********************************************************************
* Program name: "RDMOD16X.C" *
* Compiler used: BSO/Tasking C166 *
* Task: Source File for procedure rd_modata_16x *
* belonging to Siemens ApNote AP2922 *
* "'C' CAN Driver Routines for the C166 family" *
* *
* Last modifications: April 28nd 1997 *
* Version: 1.0 *
* Authors: Axel Wolf, SCI Cupertino *
* Dr. Jens Barrenscheen, HL MC PD, Munich *
*********************************************************************/
extern unsigned int *id_ptr_16x[16]; ///< pointer to message id's (UAReg)
extern unsigned char *db0_ptr_16x[16]; ///< pointer to 'databyte 0's
extern unsigned int *msgctrl_ptr_16x[16]; ///< pointer to message control registers
extern unsigned char *msgconf_ptr_16x[16]; ///< pointer to message configuration registers
extern unsigned char dir_bit_16x[16]; ///< DIR bits MO 1...15
extern unsigned char xtd_bit_16x[16]; ///< XTD bits MO 1...15
extern unsigned char dlc_16x[16]; ///< data byte lengths MO 1...15
/**
* Use this function to read received data (and the message id) from the specified message object (#1..#14).
*
* \param nr Number of the message object to read from (1..14)
* \param *downl_data_ptr Pointer to a buffer where the received data will be put.
* \param *mo_id_ptr Pointer to a long where the message id of the newly received message will be put.
* \param *mo_dlc_ptr Pointer to a character where the length of the received message will be put.
*
* \warning *downl_data_ptr must point to an array large enough to hold all received data. Always make this
* large enough for the largest possible amount of payload, being 8 bytes.
*
* \note The reading of the data bytes is repeated if a new message comes in
* for message 'nr' during the data bytes are read, because the CAN module
* sets NEWDAT in this case.
*/
void rd_modata_16x(unsigned char nr, unsigned char *downl_data_ptr, unsigned long *mo_id_ptr, unsigned char *mo_dlc_ptr)
{
unsigned char i, dummy_char;
unsigned char *dummy_dbptr;
unsigned int *dummy_idptr;
unsigned int dummy_int1, dummy_int2;
if ((nr<15) && (nr)) {
do {
dummy_char=*msgconf_ptr_16x[nr];
// added hp 2003-02-24:
*mo_dlc_ptr = (dummy_char>>4);
dummy_idptr=id_ptr_16x[nr];
if (xtd_bit_16x[nr]) { /* calculate XTD ID: */
dummy_int1=*dummy_idptr++;
dummy_int2=*dummy_idptr;
dummy_int1=(dummy_int1<<8)+(dummy_int1>>8);
dummy_int2=(dummy_int2<<8)+(dummy_int2>>8);
*mo_id_ptr=((((unsigned long)(dummy_int1))<<16) + dummy_int2)>>3;
} else { /* calculate STD ID: */
dummy_int1=*dummy_idptr;
*mo_id_ptr=(unsigned long) (((dummy_int1<<8)+(dummy_int1>>8))>>5);
}
// end of addition
/* store actual data length code */
dlc_16x[nr]=(dummy_char>>4);
/* clr NEWDAT and INTPND */
*msgctrl_ptr_16x[nr]=0xfdfd;
/* load dummy ptr (db 0) */
dummy_dbptr=db0_ptr_16x[nr];
/* move data bytes from MO's data bytes to download buffer */
for (i=0;i<dlc_16x[nr];i++)
*downl_data_ptr++ = *dummy_dbptr++;
} while (*msgctrl_ptr_16x[nr] & 0x0200); /* while NEWDAT=1 */
}
}