iLLD_TC27xD  1.0
How to use the SENT Interface driver?
Collaboration diagram for How to use the SENT Interface driver?:

This SENT interface driver provides functions to communicate with external sensors.

Preparation

Include Files

Include following header file into your C code:

Variables

Declare SENT module and channel handles as global variables in your C code. If multiple SENT channels should be serviced, it makes sense to declare the SENT channel handle as an array:

#define TESTED_SENT_CHANNELS 3
static IfxSent_Sent sent;
static IfxSent_Sent_Channel sentChannel[TESTED_SENT_CHANNELS];

Interrupt Handler Installation

See also How to define Interrupts?

Define priorities for the Interrrupt handler. This is normally done in the Ifx_IntPrioDef.h file:

#define IFX_INTPRIO_SENT_CHANNEL 1

Add the interrupt service routine to your C code. It has to call the SENT interrupt handler by passing the SENT channel handle:

void SentInterruptHandler(IfxSent_Sent_Channel *channel);
IFX_INTERRUPT(sentChannelISR, 0, IFX_INTPRIO_SENT_CHANNEL)
{
int i;
for(i=0; i<TESTED_SENT_CHANNELS; ++i)
{
SentInterruptHandler(&sentChannel[i]);
}
}

Note: the SentInterruptHandler function is not part of the interface driver, but has to be implemented in the application. A template can be found below under Interrupt Service Handler

Finally install the interrupt handlers in your initialisation function:

// install interrupt handler
IfxCpu_Irq_installInterruptHandler(&sentChannelISR, IFX_INTPRIO_SENT_CHANNEL);

Module Initialisation

The module initialisation can be done in the same function. Here an example for SENT and SPC mode:

// create module config
IfxSent_Sent_initModuleConfig(&sentConfig, &MODULE_SENT);
// initialize module
//IfxSent_Sent sent; // defined globally
IfxSent_Sent_initModule(&sent, &sentConfig);

Channel Initialisation

After the module has been initialized, one or more SENT channels can be configured.

Here an example for three SENT channels in SENT and SPC mode:

// create channel config
IfxSent_Sent_ChannelConfig sentChannelConfig;
IfxSent_Sent_initChannelConfig(&sentChannelConfig, &sent);
// define tUnit of the external sensor
sentChannelConfig.tUnit = 3.0E-6;
// ISR priorities and interrupt target
sentChannelConfig.interrupt.priority = IFX_INTPRIO_SENT_CHANNEL;
int i;
for(i=0; i<TESTED_SENT_CHANNELS; ++i)
{
// pin configuration
const IfxSent_Sent_Pins sentPins[TESTED_SENT_CHANNELS] =
{
{ // Channel 0
},
{ // Channel 1
},
{ // Channel 2
},
};
sentChannelConfig.pins = &sentPins[i];
// set channel
sentChannelConfig.channelId = (IfxSent_ChannelId)i;
// initialize channel
IfxSent_Sent_initChannel(&sentChannel[i], &sentChannelConfig);
}

Interrupt Service Handler

The ISR has to be implemented in the application. Following template can be used to react on the events:

void SentInterruptHandler(IfxSent_Sent_Channel *channel)
{
Ifx_SENT_CH_INTSTAT interruptStatus = IfxSent_Sent_getAndClearInterruptStatus(channel);
if( interruptStatus.U )
{
// check for error conditions
if (interruptStatus.U & IFXSENT_INTERRUPT_STATUS_ERROR_FLAGS)
{
// * Receive Buffer Overflow
// * This bit is set after a frame has been received while the old one was
// * not read from RDRx. I.e. the kernel wants to set any of the two
// * interrupts RSI and RDI and finds any of these two interrupts already
// * set. The old data is overwritten by the new data.
// *
if (interruptStatus.B.RBI)
{
// insert your error handling code here
}
// * Transmit Buffer Underflow
// * This bit is set after data has been completely transferred (PLEN
// * exceeded) and no new data was written to SCRx.
// *
if (interruptStatus.B.TBI)
{
// insert your error handling code here
}
// * Frequency Range Error
// * This bit is set after a Synchronization / Calibration pulse was
// * received that deviates more than +- 25% from the nominal value.
// * The referring data is ignored.
// *
if (interruptStatus.B.FRI)
{
// insert your error handling code here
}
// * Frequency Drift Error
// * This bit is set after a subsequent Synchronization / Calibration
// * pulse was received that deviates more than 1.5625% (1/64) from its
// * predecessor.
// *
if (interruptStatus.B.FDI)
{
// insert your error handling code here
}
// * Wrong Number of Nibbles
// * This bit is set after a more nibbles have been received than expected
// * or a Synchronization / Calibration Pulse is received too early thus
// * too few nibbles have been received
// *
if (interruptStatus.B.NNI)
{
// insert your error handling code here
}
// * Nibbles Value out of Range
// * This bit is set after a too long or too short nibble pulse has been
// * received. I.e. value < 0 or value > 15.
// *
if (interruptStatus.B.NVI)
{
// insert your error handling code here
}
// * CRC Error
// * This bit is set if the CRC check fails.
// *
if (interruptStatus.B.CRCI)
{
// insert your error handling code here
}
// * Wrong Status and Communication Nibble Error
// * In standard Serial Frame Mode (RCR.ESF is cleared), this bit is set
// * if the Status and Communication nibble shows a start bit in a frame
// * other than frame number n x 16.
// * In Extended Serial Frame Mode this bit is without function.
// *
if (interruptStatus.B.WSI)
{
// insert your error handling code here
}
// * Serial Data CRC Error
// * This bit is set if the CRC of the serial message fails.
// * In Extended Serial Message Format, this includes a check of the Serial
// * Communication Nibble for correct 0 values of bit 3 in frames 7, 13 and 18.
// *
if (interruptStatus.B.SCRI)
{
// insert your error handling code here
}
// * Watch Dog Error
// * This bit is set if the Watch Dog Timer of the channel expires.
// *
if (interruptStatus.B.WDI)
{
// insert your error handling code here
}
}
// transaction events
// * Receive Data
// * RDI is activated when a received frame is moved to a Receive Data
// * Register RDR. Both RDI and RSI will be issued together in normal use
// * cases where the frame size is not bigger than 8 nibbles and CRC is
// * correct or not checked (if RCRx.CDIS is cleared).
// *
if (interruptStatus.B.RDI)
{
// * Ignore RDI bit, useful only when Frame Length is greater than
// * 8 nibbles since it can indicate that end of frame
// *
}
// * Receive Success
// * This bit is set at the successfully received end of a frame.
// * Depending on bit RCRx.CDIS this indicates a successful check of the CRC.
// *
if (interruptStatus.B.RSI)
{
// here you could handle the incoming frame:
// do something with the incoming data
}
// * Transfer Data
// * This bit is set after the trigger condition was detected. Data to be
// * transferred has been moved internally. Thus a new value can be written
// * to SCRx. This can be used for back to back transfers.
// *
if (interruptStatus.B.TDI)
{
}
// * Serial Data Received
// * This bit is set after all serial data bits have been received via the
// * Status and Communication nibble. Depending on bit RCRx.SCDIS this
// * indicates a successful check of the CRC.
// *
if (interruptStatus.B.SDI)
{
// here you could handle the incoming message:
// decode incoming message
// do something with the incoming message
}
}
}

Frame Decoding

Following code snippet shows, how incoming data of a TLE4998S device can be decoded:

static void parseSensorData(IfxSent_Sent_Frame *frame)
{
uint32 data = frame->data;
uint8 statusNibble = frame->statusNibble;
// select B range [mT]
const uint8 rangeValTable[4] = { 200, 100, 50, 0 };
uint8 rangeVal = rangeValTable[statusNibble & 3];
uint16 hallVal = (short)((((data & 0xFFFF) * rangeVal) / 0x7FFF) - rangeVal);
uint16 temperature = ((short)((data >> 16) & 0x00FF) - 55);
// do something with the values here...
}