/*
 * Copyright 2021 MindMotion Microelectronics Co., Ltd.
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "board_init.h"

/*
 * Definitions.
 */
#define ENET_PHY_ADDR                      0x01      /* Select PHY address. */
#define ENET_PHY_CONTROLREG                0u        /* PHY control register address. */
#define ENET_PHY_STATUSREG                 1u        /* PHY status register sddress. */
#define ENET_PHY_RESET                     0x8000    /* Set PHY reset, use in ENET_PHY_CR registers */
#define ENET_PHY_SPEED100M                 0x2000    /* Set PHY speed. */
#define ENET_PHY_FULLDUPLEX                0x0100    /* Set PHY duplex mode about full duplex. */
#define ENET_PHY_LINK                      0x0004    /* PHY link-up. */
#define ENET_PHY_UNIDIRECTIONAL            0x0080    /* PHY has the ability to encode and transmit data from PHY through MII interface, regardless of whether PHY has determined that an effective link has been connected and established. */
#define ENET_PHY_AUTONEGOTIATION           0x1000    /* PHY auto negotiation. */
#define ENET_TX_BUFLEN1                    208u      /* Tx buffer1 length. */
#define ENET_TX_BUFLEN2                    134u      /* Tx bufferw length. */

/*
 * Variables.
 */
ENET_TxDmaDesp_Type TxDmaDespTab[5u];

uint8_t app_enet_txbuf1[ENET_TX_BUFLEN1]={
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x38, 0xf3, 0xab, 0x4e, 0x3e, 0xa9, 0x08, 0x00, 0x45, 0x00,
0x01, 0x48, 0x34, 0x17, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, 0x15, 0xe2, 0x01, 0x01, 0x06, 0x00, 0x73, 0x39,
0x15, 0xd6, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xf3, 0xab, 0x4e, 0x3e, 0xa9, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xbb, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

uint8_t app_enet_txbuf2[ENET_TX_BUFLEN2] = {
0xdd, 0xee, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x01, 0x3d, 0x07, 0x01,
0x38, 0xf3, 0xab, 0x4e, 0x3e, 0xa9, 0x0c, 0x0f, 0x44, 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x2d,
0x4d, 0x43, 0x52, 0x37, 0x47, 0x35, 0x41, 0x3c, 0x08, 0x4d, 0x53, 0x46, 0x54, 0x20, 0x35, 0x2e,
0x30, 0x37, 0x0e, 0x01, 0x03, 0x06, 0x0f, 0x1f, 0x21, 0x2b, 0x2c, 0x2e, 0x2f, 0x77, 0x79, 0xf9,
0xfc, 0xff, 0x00, 0x00, 0x00, 0x00
};

/*
 * Declerations.
 */
void app_enet_init_smi();
void app_enet_init_mac();
void app_enet_init_dma();
void app_enet_tx();

/*
 * Functions.
 */
int main(void)
{
    BOARD_Init();

    /* Initialization enet. */
    app_enet_init_smi();
    app_enet_init_mac();
    app_enet_init_dma();

    while (1)
    {
        printf("please press any key.");
        getchar();
        app_enet_tx();
        printf("app_enet_tx() done.\r\n");
    }
}

/* Initlization enet smi. */
void app_enet_init_smi()
{
    uint32_t *m_enet_smi_data = 0u;
    /* Initialization smi. */
    ENET_InitSmi(BOARD_DEBUG_ENET_PORT, ENET_SmiClockAlt_Alt1);
    ENET_WriteMacPhyReg(BOARD_DEBUG_ENET_PORT, ENET_PHY_ADDR, ENET_PHY_CONTROLREG, ENET_PHY_RESET);
    ENET_ReadMacPhyReg(BOARD_DEBUG_ENET_PORT, ENET_PHY_ADDR, ENET_PHY_CONTROLREG, m_enet_smi_data);
    while (0u != (*m_enet_smi_data & ENET_PHY_RESET) )
    {
        ENET_ReadMacPhyReg(BOARD_DEBUG_ENET_PORT, ENET_PHY_ADDR, ENET_PHY_CONTROLREG, m_enet_smi_data);
    }
    /* Set PHY. */
    uint16_t temp = ENET_PHY_SPEED100M | ENET_PHY_FULLDUPLEX;
    temp &= ~ENET_PHY_AUTONEGOTIATION;
    ENET_WriteMacPhyReg(BOARD_DEBUG_ENET_PORT,ENET_PHY_ADDR, ENET_PHY_CONTROLREG, temp);
    ENET_ReadMacPhyReg(BOARD_DEBUG_ENET_PORT, ENET_PHY_ADDR, ENET_PHY_STATUSREG, m_enet_smi_data);
    while( 0u == (*m_enet_smi_data & ENET_PHY_LINK) || (0u != (*m_enet_smi_data & ENET_PHY_UNIDIRECTIONAL) ) )
    {
        ENET_ReadMacPhyReg(BOARD_DEBUG_ENET_PORT, ENET_PHY_ADDR, ENET_PHY_STATUSREG, m_enet_smi_data);
    }
}

/* Initlization enet mac. */
void app_enet_init_mac()
{
    ENET_Init_Type enet_init;

    /* Initialization mac. */
    enet_init.SourceAddrReplace = ENET_SourceAddrReplaceAlt_Alt0;
    enet_init.StripCRC = false;
    enet_init.DisableWatchdog = false;
    enet_init.DisableJabberCount = false;
    enet_init.InterframeGap = ENET_InterFrameGap_96;
    enet_init.EnableLoopback = false;
    enet_init.DuplexMode = ENET_DuplexMode_FullDuplex;
    enet_init.EnableIPChecksumOffload = false;
    enet_init.EnableAutoStripCRCPAD = false;

    ENET_InitMacController(BOARD_DEBUG_ENET_PORT, &enet_init);
}

/* Initlization enet dma. */
void app_enet_init_dma()
{
    ENET_Init_Type enet_init;

    /* initialization dma. */
    enet_init.DmaXferPrior = ENET_DmaXferPrior_CyclicPriorRxTx1;
    enet_init.EnableAdvancedDesp = false;
    enet_init.EnableOperateOnSecondFrame = false;
    enet_init.TxFifoMode = ENET_FifoXferMode_StoreForward;
    enet_init.RxFifoMode = ENET_FifoXferMode_StoreForward;
    enet_init.MultipleProgrammableBurstLen = false;
    enet_init.TxBurstLen = ENET_DmaBurstLen_32Beat;
    enet_init.RxBurstLen = ENET_DmaBurstLen_32Beat;
    enet_init.TxThreshold = ENET_TxThreshold_64;
    enet_init.RxThreshold = ENET_RxThreshold_64;

    ENET_InitDmaController(BOARD_DEBUG_ENET_PORT, &enet_init);
}

/* Set enet tx dma descriptor. */
void app_enet_tx()
{
    ENET_LinkTxDmaDesp(BOARD_DEBUG_ENET_PORT, &TxDmaDespTab[0u], app_enet_txbuf1, ENET_TX_BUFLEN1, &TxDmaDespTab[0u]);
    ENET_LinkTxDmaDesp(BOARD_DEBUG_ENET_PORT, &TxDmaDespTab[1u], app_enet_txbuf2, ENET_TX_BUFLEN2, &TxDmaDespTab[0u]);
    ENET_EnableTxDma(BOARD_DEBUG_ENET_PORT, true);
    while ( 0u == (ENET_GetStatus(BOARD_DEBUG_ENET_PORT) & ENET_STATUS_MAC_TX_FIFO_WRITE_ACTIVE) )
    {
    }
    while ( 0u == (ENET_GetDmaStatus(BOARD_DEBUG_ENET_PORT) & ENET_INT_TX_DONE) )
    {
    }
    ENET_ClearDmaStatus(BOARD_DEBUG_ENET_PORT, ENET_INT_TX_DONE);
    ENET_EnableTxDma(BOARD_DEBUG_ENET_PORT, false);
}

/* EOF. */
