Part Number: TMS320F280025
C2k Team,
I'm trying to do a LIN MITM attack on some equipment and am trying to write some drivers for the LIN peripheral. It would appear there is ZERO documentation or examples of how to propely do a slave response. The only things I've been able to find is this:
In the example posted here, the user is only able to respond to a single ID. This example also is giving me vibes that the underlying state machine wants to see a TX ID match before it will allow a slave response? Is this true?
I'm trying to write an interrupt based driver where I manage all the comms with the processor and don't use any filtering/masking. I'm able to RX messages all day long. When I get an ID interrupt that is for a slave response message I copy the data into the tx buffer but it never gets sent out and my isTxReady check fails after the first time around.
Here's my ISR:
__interrupt void
LIN_linAHandler(void)
{
uint16_t interruptCause;
//
// Read the high priority interrupt vector
//
interruptCause = LIN_getInterruptLine0Offset(LINA_BASE);
switch(interruptCause)
{
case LIN_VECT_ID:
{
linMessageObject_t *message;
volatile uint16_t messageId;
messageId = LIN_getRxIdentifier(LINA_BASE);
message = LIN_linGetMessageObjectById(messageId);
if(message != 0)
{
//Set frame length so it may be received correctly
LIN_setFrameLength(LINA_BASE, message->len);
//Calculate period
// message->period = timer0getCount() - message->lastRxTime;
// message->lastRxTime = timer0getCount();
//If the message is TX its showtime baybee!
if((message->direction == LINMESSAGE_TO_MASTER) && injectionActive)
{
// LIN_linTx(LINA_BASE, message);
if(LIN_isTxReady(LINA_BASE))
{
//
// Write data to Tx Buffer of LINA
//
LIN_sendData(LINA_BASE, message->originalData);
}
}
//If the message is RX we are done
}
//Clear Interrupt Status
LIN_clearInterruptStatus(LINA_BASE, LIN_INT_ID);
break;
}
case LIN_VECT_RX:
{
linMessageObject_t *message;
volatile uint16_t dumpBuffer[8];
message = LIN_linGetMessageObjectById(LIN_getRxIdentifier(LINA_BASE));
if(message != 0)
{
if((message->direction == LINMESSAGE_TO_SLAVE) )//|| !injectionActive)
{
LIN_getData(LINA_BASE, message->originalData);
}else
{
//We gots a problem
//Data in the rx buffer we don't know what to do with.
// ESTOP0;
LIN_getData(LINA_BASE, dumpBuffer);
}
}else
{
LIN_getData(LINA_BASE, dumpBuffer);
}
LIN_clearInterruptStatus(LINA_BASE, LIN_INT_RX);
break;
}
case LIN_VECT_TX:
{
LIN_clearInterruptStatus(LINA_BASE, LIN_INT_TX);
break;
}
case LIN_VECT_CE:
{
LIN_clearInterruptStatus(LINA_BASE, LIN_INT_CE);
// ESTOP0;
break;
}
case LIN_VECT_FE:
{
LIN_clearInterruptStatus(LINA_BASE, LIN_INT_FE);
// ESTOP0;
break;
}
case LIN_VECT_OE:
{
LIN_clearInterruptStatus(LINA_BASE, LIN_INT_OE);
// ESTOP0;
break;
}
case LIN_VECT_BE:
{
LIN_clearInterruptStatus(LINA_BASE, LIN_INT_BE);
// ESTOP0;
break;
}
case LIN_VECT_NRE:
{
LIN_clearInterruptStatus(LINA_BASE, LIN_INT_NRE);
// ESTOP0;
break;
}
case LIN_VECT_PBE:
{
LIN_clearInterruptStatus(LINA_BASE, LIN_INT_PBE);
// ESTOP0;
break;
}
default:
ESTOP0;
}
LIN_clearGlobalInterruptStatus(LINA_BASE, LIN_INTERRUPT_LINE0);
//
// Acknowledge this interrupt located in group 8
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
}
Any idea what I'm doing wrong? It's super duper frustrating when a key function like this isn't documented and there are no examples.