32F417 - how to prevent low_level_output() (in ethernetif.c) overwriting the last DMA buffer?
It seems that one has to wait on the three TPS bits = 000 in DMASR.
I fixed the problem by putting
if ( (((heth->Instance)->DMASR) & (0x7 << 20)) != 0 ) {}
at the end of HAL_ETH_TransmitFrame().
That loop should not hang unless the silicon is defective - right?
This is the code which is all over the internet, and I think the check of whether the buffer is available is in the wrong place. It should be BEFORE the memcpy().
/* Check if the length of data to copy is bigger than Tx buffer size*/
while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE )
{
/* Copy data to Tx buffer*/
memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) );
/* Point to next descriptor */
DmaTxDesc = (ETH_DMADESCTypeDef *)(DmaTxDesc->Buffer2NextDescAddr);
/* Check if the buffer is available */
if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET)
{
errval = ERR_USE;
goto error;
}
buffer = (u8 *)(DmaTxDesc->Buffer1Addr);
byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset);
payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset);
framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset);
bufferoffset = 0;
}