#include "lip/ll/lip_ll.h"
#include "chip.h"




t_lip_errs lip_ll_init(t_lip_init_stage stage, int flags) {
    t_lip_errs err = LIP_ERR_SUCCESS;
    switch (stage) {
    case LIP_INIT_STAGE_PHY_INTF_INIT:
        CHIP_REGS_EXTEN->CTR |= CHIP_REGFLD_EXTEN_CTR_ETH_RGMII;

        /* сброс модуля и разрешение необходимых клоков */
        chip_per_rst(CHIP_PER_ID_ETH_MAC);
        chip_per_clk_en(CHIP_PER_ID_ETH_MAC);
        chip_per_clk_en(CHIP_PER_ID_ETH_TX);
        chip_per_clk_en(CHIP_PER_ID_ETH_RX);

        CHIP_PIN_CONFIG(CHIP_PIN_PB12_ETH_RGMII_MDC);
        CHIP_PIN_CONFIG(CHIP_PIN_PB13_ETH_RGMII_MDIO);

        CHIP_PIN_CONFIG(CHIP_PIN_PA7_ETH_RGMII_TXD0);
        CHIP_PIN_CONFIG(CHIP_PIN_PC4_ETH_RGMII_TXD1);
        CHIP_PIN_CONFIG(CHIP_PIN_PC5_ETH_RGMII_TXD2);
        CHIP_PIN_CONFIG(CHIP_PIN_PB0_ETH_RGMII_TXD3);
        CHIP_PIN_CONFIG(CHIP_PIN_PA3_ETH_RGMII_TXEN);
        CHIP_PIN_CONFIG(CHIP_PIN_PA2_ETH_RGMII_GTXC);

        CHIP_PIN_CONFIG(CHIP_PIN_PC2_ETH_RGMII_RXD0);
        CHIP_PIN_CONFIG(CHIP_PIN_PC3_ETH_RGMII_RXD1);
        CHIP_PIN_CONFIG(CHIP_PIN_PA0_ETH_RGMII_RXD2);
        CHIP_PIN_CONFIG(CHIP_PIN_PA1_ETH_RGMII_RXD3);
        CHIP_PIN_CONFIG(CHIP_PIN_PC1_ETH_RGMII_RXCTL);
        CHIP_PIN_CONFIG(CHIP_PIN_PC0_ETH_RGMII_RXC);



#if 0
        CHIP_PIN_CONFIG(LIP_ETH_PIN_REF_CLK);
        CHIP_PIN_CONFIG(LIP_ETH_PIN_CRS_DV);
        CHIP_PIN_CONFIG(LIP_ETH_PIN_RXD0);
        CHIP_PIN_CONFIG(LIP_ETH_PIN_RXD1);
        CHIP_PIN_CONFIG(LIP_ETH_PIN_TX_EN);
        CHIP_PIN_CONFIG(LIP_ETH_PIN_TXD0);
        CHIP_PIN_CONFIG(LIP_ETH_PIN_TXD1);
#endif
        break;
    case LIP_INIT_STAGE_MAC_INIT:
        //err = f_mac_init(flags);
        break;
    case LIP_INIT_STAGE_MAC_START:
        //f_eth_config(lip_mac_phy_mode());
        //f_eth_start();
        break;
    }
    return err;
}

void lip_ll_stop(void) {

}

void lip_ll_close(void) {

}

void lip_ll_set_mac_addr(const uint8_t *mac_addr) {

}



t_lip_errs lip_ll_mdio_write_start(uint8_t phyaddr, uint8_t regaddr, uint16_t value) {
    CHIP_REGS_ETH->MACMIIDR = LBITFIELD_SET(CHIP_REGFLD_ETH_MACMIIDR_MD, value);
    CHIP_REGS_ETH->MACMIIAR = LBITFIELD_SET(CHIP_REGFLD_ETH_MACMIIAR_PA, phyaddr)
                            | LBITFIELD_SET(CHIP_REGFLD_ETH_MACMIIAR_MR, regaddr)
                            | LBITFIELD_SET(CHIP_REGFLD_ETH_MACMIIAR_CR, 0)
                            | LBITFIELD_SET(CHIP_REGFLD_ETH_MACMIIAR_MW, 1)
                            | LBITFIELD_SET(CHIP_REGFLD_ETH_MACMIIAR_MB, 1)
        ;


    return LIP_ERR_SUCCESS;
}


t_lip_errs lip_ll_mdio_read_start(uint8_t phyaddr, uint8_t regaddr) {
    CHIP_REGS_ETH->MACMIIAR = LBITFIELD_SET(CHIP_REGFLD_ETH_MACMIIAR_PA, phyaddr)
    | LBITFIELD_SET(CHIP_REGFLD_ETH_MACMIIAR_MR, regaddr)
        | LBITFIELD_SET(CHIP_REGFLD_ETH_MACMIIAR_CR, 0)
        | LBITFIELD_SET(CHIP_REGFLD_ETH_MACMIIAR_MW, 0)
        | LBITFIELD_SET(CHIP_REGFLD_ETH_MACMIIAR_MB, 1)
        ;
    return LIP_ERR_SUCCESS;
}

bool lip_ll_mdio_rdy(void) {
    return (CHIP_REGS_ETH->MACMIIAR & CHIP_REGFLD_ETH_MACMIIAR_MB) == 0;
}

t_lip_errs lip_ll_mdio_data(uint16_t *data) {
    *data = LBITFIELD_GET(CHIP_REGS_ETH->MACMIIDR, CHIP_REGFLD_ETH_MACMIIDR_MD);
    return LIP_ERR_SUCCESS;
}

uint8_t *lip_ll_tx_frame_buf_prepare(const t_lip_tx_frame_info *info, uint32_t size) {

    return NULL;
}

t_lip_errs lip_ll_tx_frame(t_lip_tx_frame *frame) {

    return LIP_ERR_SUCCESS;
}

void lip_ll_pull(void) {

}


#ifdef LIP_USE_IGMP
/************************************************************************
 * Вызывается при подключение к mcast группе с заданным mac-адресом =>
 *   после вызова должны принимать пакеты по заданному адресу
 ************************************************************************/
t_lip_errs lip_ll_join(const uint8_t* mac) {
    //LPC_EMAC->RxFilterCtrl |= LPC_EMAC_RxFilterCtrl_AcceptMulticastEn_Msk;
    return LIP_ERR_SUCCESS;
}

/***************************************************************************
 * Вызывается при отключение от mcast гурппы. После вызова порт может не
 * принимать больше пакеты по заданному mac-адресу
 ***************************************************************************/
t_lip_errs lip_ll_leave(const uint8_t* mac) {
    return LIP_ERR_SUCCESS;
}
#endif
