1 | /**
|
2 | * @brief Transmits a packet, from application buffer, pointed by ppkt.
|
3 | * @param ppkt: pointer to application packet buffer to transmit.
|
4 | * @param FrameLength: Tx Packet size.
|
5 | * @retval : ETH_ERROR: in case of Tx desc owned by DMA
|
6 | * ETH_SUCCESS: for correct transmission
|
7 | */
|
8 | uint32_t ETH_HandleTxPkt(uint8_t *ppkt, uint16_t FrameLength)
|
9 | {
|
10 | uint32_t offset = 0;
|
11 |
|
12 | /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
|
13 | if((DMATxDescToSet->Status & ETH_DMATxDesc_OWN) != (uint32_t)RESET)
|
14 | {
|
15 | /* Return ERROR: OWN bit set */
|
16 | return ETH_ERROR;
|
17 | }
|
18 |
|
19 | /* Copy the frame to be sent into memory pointed by the current ETHERNET DMA Tx descriptor */
|
20 | for(offset=0; offset<FrameLength; offset++)
|
21 | {
|
22 | (*(__IO uint8_t *)((DMATxDescToSet->Buffer1Addr) + offset)) = (*(ppkt + offset));
|
23 | }
|
24 |
|
25 | /* Setting the Frame Length: bits[12:0] */
|
26 | DMATxDescToSet->ControlBufferSize = (FrameLength & ETH_DMATxDesc_TBS1);
|
27 | /* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */
|
28 | DMATxDescToSet->Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS;
|
29 | /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
|
30 | DMATxDescToSet->Status |= ETH_DMATxDesc_OWN;
|
31 | /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
|
32 | if ((ETH->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
|
33 | {
|
34 | /* Clear TBUS ETHERNET DMA flag */
|
35 | ETH->DMASR = ETH_DMASR_TBUS;
|
36 | /* Resume DMA transmission*/
|
37 | ETH->DMATPDR = 0;
|
38 | }
|
39 |
|
40 | /* Update the ETHERNET DMA global Tx descriptor with next Tx decriptor */
|
41 | /* Chained Mode */
|
42 | if((DMATxDescToSet->Status & ETH_DMATxDesc_TCH) != (uint32_t)RESET)
|
43 | {
|
44 | /* Selects the next DMA Tx descriptor list for next buffer to send */
|
45 | DMATxDescToSet = (ETH_DMADESCTypeDef*) (DMATxDescToSet->Buffer2NextDescAddr);
|
46 | }
|
47 | else /* Ring Mode */
|
48 | {
|
49 | if((DMATxDescToSet->Status & ETH_DMATxDesc_TER) != (uint32_t)RESET)
|
50 | {
|
51 | /* Selects the first DMA Tx descriptor for next buffer to send: last Tx descriptor was used */
|
52 | DMATxDescToSet = (ETH_DMADESCTypeDef*) (ETH->DMATDLAR);
|
53 | }
|
54 | else
|
55 | {
|
56 | /* Selects the next DMA Tx descriptor list for next buffer to send */
|
57 | DMATxDescToSet = (ETH_DMADESCTypeDef*) ((uint32_t)DMATxDescToSet + 0x10 + ((ETH->DMABMR & ETH_DMABMR_DSL) >> 2));
|
58 | }
|
59 | }
|
60 | /* Return SUCCESS */
|
61 | return ETH_SUCCESS;
|
62 | }
|