This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
My customer use TMS320F280049 design DCDC with LIN communication. Under different DCDC working load, we found a LIN problem.
1. When no load, LIN communication is normal.
2. When increase load to 20A (rated power is 37A), LIN is stopped.
We use polling method for LIN communication(not interruption mode)
Here is LIN code:
Task Scheduler
Add LIN initialization and Rx progress code on below.
LIN_initModule(uint32_t base) { // // Check the arguments. // ASSERT(LIN_isBaseValid(base)); EALLOW; // // Reset LIN module // Release from hard reset // LIN_disableModule(base); LIN_enableModule(base); // // Enter Software Reset State // LIN_enterSoftwareReset(base); // // Enable LIN Mode // LIN_disableSCIMode(base); // // Set LIN mode to SLAVE // LIN_setLINMode(base, LIN_MODE_LIN_SLAVE ); // // // LIN_disableAutomaticBaudrate(base); // LIN_enableAutomaticBaudrate(base); // // Use the set frame length and not ID4/ID5 bits for length control LIN_setCommMode(base, LIN_COMM_LIN_USELENGTHVAL);// // // Setup to continue operating on emulation suspend LIN_setDebugSuspendMode(base, LIN_DEBUG_COMPLETE); // // Use Enhanced Checksum // LIN_setChecksumType(base, LIN_CHECKSUM_ENHANCED); // // Message filtering uses slave task ID byte LIN_setMessageFiltering(base, LIN_MSG_FILTER_IDSLAVE); // // Disable Internal loopback for external communication // LIN_disableIntLoopback(base); // // Enable multi-buffer mode // LIN_enableMultibufferMode(base); // // Enable parity check on received ID // LIN_enableParity(base); // // Enable transfer of data to and from the shift registers // LIN_enableDataTransmitter(base); LIN_enableDataReceiver(base); // // Enable the triggering of checksum compare on extended frames // // LIN_triggerChecksumCompare(base); // // Set LIN interrupts to disabled // LIN_disableInterrupt(base, LIN_INT_ALL); // // Set Baud Rate Settings - 100MHz Device // LIN_setBaudRatePrescaler(base, 324U, 8U); LIN_setMaximumBaudRate(base, 100000000U); // // Set response field to 1 byte // LIN_setFrameLength(base, 8U); // // Configure sync field // Sync break (13 + 5 = 18 Tbits) // Sync delimiter (1 + 3 = 4 Tbits) // LIN_setSyncFields(base, 0U, 1U); // // Set Mask ID so TX/RX match will always happen // LIN_setTxMask(base, 0xFFU); LIN_setRxMask(base, 0xFFU); // // Disable IODFT testing and external loopback mode // LIN_disableExtLoopback(base); // // Finally exit SW reset and enter LIN ready state // LIN_exitSoftwareReset(base); EDIS; } LIN_RXProcess(viod) { if(LIN_isRxMatch(LINA_BASE)) { RXID.byte1=LIN_getRxIdentifier(LINA_BASE); switch(RXID.byte1) { case 0x06: CANBUSOFFPARA.RX_06=0; HVSC_0x06RcvManage(); break; case 0xC1: CANBUSOFFPARA.RX_01=0; HVSC_0x01RcvManage(); break; case 0x20: CANBUSOFFPARA.RX_20=0; UDS_Lin_RX_Interface(); break; case 0x03: CANBUSOFFPARA.TX_03=0; HVSC_0x03TrmManage(); break; case 0x85: CANBUSOFFPARA.TX_05=0; HVSC_0x05TrmManage(); break; case 0x61: CANBUSOFFPARA.TX_21=0; UDS_Lin_TX_Interface(); break; default: break; } }else{;} }
Daniel,
This appears to be more of EMI issue than a LIN issue to me.
Hi Hareesh,
Thanks for your reply. Answer your questions firstly.
1. LIN keep working at low load, but will lose frames at high load.
2. Sorry for we hasn't bus analyzer.
3. No errors observed before LIN stops
4. When LIN stops, DCDC still can works.
5. No other communication peripheral are used now.
During debug in this days, we make a improvement at 37A full load after make changes in below code:
LIN communication keep works at 37A full load. But it sill has some frame lost.
When master node writes, use LIN_isSCIDataAvailable(LINA_BASE) function to help communication be recovered when it is interrupted.
if(LIN_isSCIDataAvailable(LINA_BASE))
{
// if(LINpara.vectorOffset == LIN_VECT_RX)
// {
RXID.RX_WAKEUP++;
RXID.byte1=LIN_getRxIdentifier(LINA_BASE);
switch(RXID.byte1)
{
case 0x06:
CANBUSOFFPARA.OvertimeCntRX_06=0;
HVSC_0x06RcvManage();
break;
case 0xC1:
CANBUSOFFPARA.OvertimeCntRX_01=0;
HVSC_0x01RcvManage();
break;
case 0x20:
CANBUSOFFPARA.OvertimeCntRX_20=0;
UDS_Lin_RX_Interface();
break;
default: break;
}
LINpara.vectorOffset=0;
}
else{;}
What we have test:
1. Capture input and output current and voltage. When communication is lost, there is no jump occurs, exclude that is caused by input and output load problems.
2. Monitor the interruption used by DCDC, monitor adc_isr, epwm1_tz_isr, cpu_timer0_isr respectively. We find that the adc_isr interruption is less be used, add LED in code to detect the time. When the load can not be increased, observe it by oscilloscope. Reduce the frequency to run adc_isr, the frame loss is still occurs. Thanks.
Hi Daniel,
What improvement did you make for LIN to work upto 37A of loading? Based on your initial post it was not working at 20A, correct?
Just trying to understand the problem. Like Hareesh mentioned it appears to be EMI related.
Regards,
Nirav
Hi Nirav and Hareesh,
To be simple, my customer has to use LIN polling mode instead of interruption example
1. Could you provide a LIN polling mode example?
2. If not, could you help check below polling code customer write? Thanks.
Call LIN_isSCIDataAvailable(LINA_BASE) for writing.
void LIN_RXProcess(void)
{
if(LIN_isSCIDataAvailable(LINA_BASE))
{
if(LINpara.vectorOffset == LIN_VECT_RX)
{
RXID.RX_WAKEUP++;
RXID.byte1=LIN_getRxIdentifier(LINA_BASE);
switch(RXID.byte1)
{
case 0x06:
CANBUSOFFPARA.OvertimeCntRX_06=0;
RXID.byte4++;
HVSC_0x06RcvManage();
break;
case 0xC1:
CANBUSOFFPARA.OvertimeCntRX_01=0;
RXID.byte5++;
HVSC_0x01RcvManage();
break;
case 0x20:
CANBUSOFFPARA.OvertimeCntRX_20=0;
UDS_Lin_RX_Interface();
break;
default: break;
}
LINpara.vectorOffset=0;
}
else{;}
}
Call LIN_isRxMatch(LINA_BASE) for reading.
void LIN_TXProcess(void)
{
if(LIN_isRxMatch(LINA_BASE))
{
RXID.RX_WAKEUP++;
RXID.byte1=LIN_getRxIdentifier(LINA_BASE);
switch(RXID.byte1)
{
case 0x03:
CANBUSOFFPARA.OvertimeCntTX_03=0;
HVSC_0x03TrmManage();
break;
case 0x85: //initial system
CANBUSOFFPARA.OvertimeCntTX_05=0;
HVSC_0x05TrmManage();
break;
case 0x61:
CANBUSOFFPARA.OvertimeCntTX_21=0;
UDS_Lin_TX_Interface();
break;
default: break;
}
LINpara.vectorOffset=0;
}
else{;}
}
Hi Daniel,
We do not have any example related to polling today, but will take an action to add that for future release.
Yes, you can use LIN_isSCIDataAvailable(LINA_BASE) function to get the RXRDY flag which needs to be polled. You can also refer to LIN chapter in TRM for more details, here is the snippet on how to use polling:
"In polling method, software can poll for the RXRDY bit and read the data from RD0 byte of the LINRD0
register once the RXRDY bit is set high. The CPU is unnecessarily overloaded by selecting the polling
method. To avoid this, you can use the interrupt or DMA method. To use the interrupt method, the SET
RX INT bit is set. To use the DMA method, the SET RX DMA bit must be set. Either an interrupt or a DMA
request is generated the moment the RXRDY bit is set. If the checksum scheme is enabled by setting the
Compare Checksum (CC) bit to 1, the checksum will be compared on the byte that is currently being
received, which is expected to be the checksum byte. The CC bit will be cleared once the checksum is
received. A CE will immediately be flagged if there is a checksum error."
Also, are you in Multi-Buffer mode?
Regards,
Nirav