#include "canr_16x.h"
#include "../ser/ser.h"
/**
* \file mask.c
*
* \author Axel Wolf, SCI Cupertino
* \author Dr. Jens Barrenscheen, HL MC PD, Munich
* \author Hubert Piontek, University of Ulm
*
* Added functions to set the global reception mask and low-level interface for the publisher/subscriber library.
*/
/**
* Each incoming message is filtered through the global mask. Each bit that is set to 1 in the
* global mask must match the corresponding id bits of the receiving message objects. Each bit that is
* set to 0 means "don't care" when comparing the id of the incoming message with the receive objects.
*
* \param mask Only the lower 29 bits are used. As the layout of the CAN registers within
* the C166 is kind of strange, we need to do lots of shifting. The exact layout is of no
* interest to the user of this driver, because it takes care of that. If anyone is interested
* in the details behind this, (s)he may consult the C166 user's manuals.
*/
void set_global_mask( unsigned long mask )
{
UGML = ((mask >> 21) & 0xff) | (((mask >> 13) & 0xff) << 8);
LGML = ((mask >> 5) & 0xff) | ((mask & 0x1f) << 11);
}
/**
* This function handles everything from (re-)defining the first message object
* to loading the data and transmitting it over the CAN bus. It is used by the publisher/subscriber library.
* Can also be very useful if you "just want to send a message" ;)
*
* \param *cm pointer to a canmsg struct holding the message to be sent.
*
* \warning Always uses the first message object. Do not use that one otherwise or do not use this function.
*/
void can_write(canmsg *cm)
{
// double check the size
if(cm->len > 8)
cm->len = 8;
// (re)define the (first) message object.
def_mo_16x( 1, USE_XTID, cm->id, DIR_XMIT, cm->len, NO_TX_INT, NO_RX_INT );
// load the payload into the message object
ld_modata_16x( 1, cm->d );
// transmit the message
send_mo_16x( 1 );
}
/**
* This function checks the specified message object for new data.
*
* \param nr number of the message object to read from
* \param *cm pointer to a canmsg struct that will hold the received data.
*
* \return new data indication
* \retval 0 There is no new data, *cm is not touched.
* \retval >0 There is new data. The message had at least 1 byte of payload.
* The data (and status info like the message id) is copied to *cm,
* and the length of the message is returned.
* \retval -1 There is new data. The message had no payload.
* The data (and status info) is copied to *cm, but
*/
int can_read(int nr, canmsg *cm)
{
unsigned char len;
unsigned long id;
// check for the last object
if( nr < 15 ) {
// new data?
if( !check_mo_16x( nr ) )
return 0;
// yes, get it.
rd_modata_16x( nr, cm->d, &id, &len );
cm->id = id;
} else {
// new data?
if( !check_mo15_16x() )
return 0;
// yes, get it.
rd_mo15_16x( cm->d, &id, &len );
cm->id = id;
}
// generate a cool return value ;)
cm->len = (len)?((int)len):-1;
return cm->len;
}