Part Number: TMS320F28388D
Other Parts Discussed in Thread: C2000WARE
Hi,
The GenericISR found in the Ethernet portion of the C2000Ware Driverlib for the Communication Manager (CM) is giving me trouble by (on rare occasions) getting stuck in an unending interrupt loop caused by the interrupt for the Transmit Buffer Unavailable (TBU) condition. Inside the GenericISR interrupt function, the section that handles the TBU interrupt do nothing but attempt to clear the TBU and NIS interrupt flags; unsucessfully as I've mentioned that the GenericISR ends up being caught in a loop. The code that handles the TBU condition can be found below:
/* Check for Normal Interrupt (NIS) and TX Buffer Unavailable (TBU) */
else if((ETHERNET_DMA_CH0_STATUS_NIS | ETHERNET_DMA_CH0_STATUS_TBU) ==
(HWREG(Ethernet_device_struct.baseAddresses.enet_base +
ETHERNET_O_DMA_CH0_STATUS) &
(uint32_t)(ETHERNET_DMA_CH0_STATUS_NIS |
ETHERNET_DMA_CH0_STATUS_TBU)))
{
#ifdef ETHERNET_DEBUG
Ethernet_txChan0BufUnavail++;
#endif
/*
* Clear the NIS and TBU status bit. These MUST be
* cleared together!
*/
Ethernet_clearDMAChannelInterrupt(
Ethernet_device_struct.baseAddresses.enet_base,
ETHERNET_DMA_CHANNEL_NUM_0,
ETHERNET_DMA_CH0_STATUS_NIS | ETHERNET_DMA_CH0_STATUS_TBU);
}
The F28388D TRM wasn't of much help either. Here is what it said for what might be a way to handle a TBU condition:
To resume processing the Transmit descriptors, the application should do the following: 1. Change the ownership of the descriptor by setting Bit 31 of TDES3. 2. Issue a Transmit Poll Demand command. For ring mode, the application should advance the Transmit Descriptor Tail Pointer register of a channel.
I've seen variables regarding TDES3 in the ethernet.c, but I doubt there is an easy way to access the TDES3 of whatever descriptor is causing problems from the application code. Also, there is no mention of a "Transmit Poll Demand" command anywhere else in the TRM.
Finally, in the lwIP examples, enet_lwip.c, one of the first things that happen in that example is this function being called:
//
// Disable transmit buffer unavailable and normal interrupt which
// are enabled by default in Ethernet_getHandle.
//
Ethernet_disableDmaInterrupt(Ethernet_device_struct.baseAddresses.enet_base,
0, (ETHERNET_DMA_CH0_INTERRUPT_ENABLE_TBUE |
ETHERNET_DMA_CH0_INTERRUPT_ENABLE_NIE));
Even in your own examples you opted to disable the interrupt instead of showing users how they should handle it.
I would really like to know how to properly handle a TBU condition because right now I am opting to disable that specific interrupt if I can't find any downsides to ignoring that condition that the TBU interrupt is suppose to represent.
P.S.: This is my first time using this forum since the changes to how E2E forum posts are made so please forgive me if this post was made to the wrong topic category.