コード例 #1
0
/**
 * \brief KSZ8851SNL initialization function.
 *
 * \return 0 on success, 1 on communication error.
 */
uint32_t ksz8851snl_init(void)
{
    uint32_t count = 0;
    uint16_t dev_id = 0;

    /* Configure the SPI peripheral. */
    spi_enable_clock(KSZ8851SNL_SPI);
    spi_disable(KSZ8851SNL_SPI);
    spi_reset(KSZ8851SNL_SPI);
    spi_set_master_mode(KSZ8851SNL_SPI);
    spi_disable_mode_fault_detect(KSZ8851SNL_SPI);
    spi_set_peripheral_chip_select_value(KSZ8851SNL_SPI, ~(uint32_t)(1 << KSZ8851SNL_CS_PIN));
    spi_set_clock_polarity(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, SPI_CLK_POLARITY);
    spi_set_clock_phase(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, SPI_CLK_PHASE);
    spi_set_bits_per_transfer(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN,
                              SPI_CSR_BITS_8_BIT);
    spi_set_baudrate_div(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, (sysclk_get_cpu_hz() / KSZ8851SNL_CLOCK_SPEED));
    spi_set_transfer_delay(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, CONFIG_SPI_MASTER_DELAY_BS,
                           CONFIG_SPI_MASTER_DELAY_BCT);
    spi_enable(KSZ8851SNL_SPI);

    /* Get pointer to UART PDC register base. */
    g_p_spi_pdc = spi_get_pdc_base(KSZ8851SNL_SPI);
    pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);

    /* Control RSTN and CSN pin from the driver. */
    gpio_configure_pin(KSZ8851SNL_CSN_GPIO, KSZ8851SNL_CSN_FLAGS);
    gpio_set_pin_high(KSZ8851SNL_CSN_GPIO);
    gpio_configure_pin(KSZ8851SNL_RSTN_GPIO, KSZ8851SNL_RSTN_FLAGS);

    /* Reset the Micrel in a proper state. */
    do {
        /* Perform hardware reset with respect to the reset timing from the datasheet. */
        gpio_set_pin_low(KSZ8851SNL_RSTN_GPIO);
        delay_ms(100);
        gpio_set_pin_high(KSZ8851SNL_RSTN_GPIO);
        delay_ms(100);

        /* Init step1: read chip ID. */
        dev_id = ksz8851_reg_read(REG_CHIP_ID);
        if (++count > 10)
            return 1;
    } while ((dev_id & 0xFFF0) != CHIP_ID_8851_16);

    /* Init step2-4: write QMU MAC address (low, middle then high). */
    ksz8851_reg_write(REG_MAC_ADDR_0, (ETHERNET_CONF_ETHADDR4 << 8) | ETHERNET_CONF_ETHADDR5);
    ksz8851_reg_write(REG_MAC_ADDR_2, (ETHERNET_CONF_ETHADDR2 << 8) | ETHERNET_CONF_ETHADDR3);
    ksz8851_reg_write(REG_MAC_ADDR_4, (ETHERNET_CONF_ETHADDR0 << 8) | ETHERNET_CONF_ETHADDR1);

    /* Init step5: enable QMU Transmit Frame Data Pointer Auto Increment. */
    ksz8851_reg_write(REG_TX_ADDR_PTR, ADDR_PTR_AUTO_INC);

    /* Init step6: configure QMU transmit control register. */
    ksz8851_reg_write(REG_TX_CTRL,
                      TX_CTRL_ICMP_CHECKSUM |
                      TX_CTRL_UDP_CHECKSUM |
                      TX_CTRL_TCP_CHECKSUM |
                      TX_CTRL_IP_CHECKSUM |
                      TX_CTRL_FLOW_ENABLE |
                      TX_CTRL_PAD_ENABLE |
                      TX_CTRL_CRC_ENABLE
                     );

    /* Init step7: enable QMU Receive Frame Data Pointer Auto Increment. */
    ksz8851_reg_write(REG_RX_ADDR_PTR, ADDR_PTR_AUTO_INC);

    /* Init step8: configure QMU Receive Frame Threshold for one frame. */
    ksz8851_reg_write(REG_RX_FRAME_CNT_THRES, 1);

    /* Init step9: configure QMU receive control register1. */
    ksz8851_reg_write(REG_RX_CTRL1,
                      RX_CTRL_UDP_CHECKSUM |
                      RX_CTRL_TCP_CHECKSUM |
                      RX_CTRL_IP_CHECKSUM |
                      RX_CTRL_MAC_FILTER |
                      RX_CTRL_FLOW_ENABLE |
                      RX_CTRL_BROADCAST |
                      RX_CTRL_ALL_MULTICAST|
                      RX_CTRL_UNICAST);

    /* Init step10: configure QMU receive control register2. */
    ksz8851_reg_write(REG_RX_CTRL2,
                      RX_CTRL_IPV6_UDP_NOCHECKSUM |
                      RX_CTRL_UDP_LITE_CHECKSUM |
                      RX_CTRL_ICMP_CHECKSUM |
                      RX_CTRL_BURST_LEN_FRAME);

    /* Init step11: configure QMU receive queue: trigger INT and auto-dequeue frame. */
    ksz8851_reg_write(REG_RXQ_CMD, RXQ_CMD_CNTL);

    /* Init step12: adjust SPI data output delay. */
    ksz8851_reg_write(REG_BUS_CLOCK_CTRL, BUS_CLOCK_166 | BUS_CLOCK_DIVIDEDBY_1);

    /* Init step13: restart auto-negotiation. */
    ksz8851_reg_setbits(REG_PORT_CTRL, PORT_AUTO_NEG_RESTART);

    /* Init step13.1: force link in half duplex if auto-negotiation failed. */
    if ((ksz8851_reg_read(REG_PORT_CTRL) & PORT_AUTO_NEG_RESTART) != PORT_AUTO_NEG_RESTART)
    {
        ksz8851_reg_clrbits(REG_PORT_CTRL, PORT_FORCE_FULL_DUPLEX);
    }

    /* Init step14: clear interrupt status. */
    ksz8851_reg_write(REG_INT_STATUS, 0xFFFF);

    /* Init step15: set interrupt mask. */
    ksz8851_reg_write(REG_INT_MASK, INT_RX);

    /* Init step16: enable QMU Transmit. */
    ksz8851_reg_setbits(REG_TX_CTRL, TX_CTRL_ENABLE);

    /* Init step17: enable QMU Receive. */
    ksz8851_reg_setbits(REG_RX_CTRL1, RX_CTRL_ENABLE);

    return 0;
}
コード例 #2
0
/**
 * \brief Initialize the PHY controller
 *
 * Call this function to initialize the hardware interface and the PHY
 * controller. When initialization is done the PHY is turned on and ready
 * to receive data.
 */
uint32_t ksz8851snl_init(void)
{
	uint32_t count = 0;
	uint16_t dev_id = 0;

	/* Initialize delay routine. */
	delay_init();

	/* Initialize the SPI interface. */
	ksz8851snl_interface_init();

	/* Reset the Micrel in a proper state. */
	do {
		ksz8851snl_hard_reset();

		/* Init step1: read chip ID. */
		dev_id = ksz8851_reg_read(REG_CHIP_ID);
		if (++count > 10)
			return 1;
	} while ((dev_id & 0xFFF0) != CHIP_ID_8851_16);

	/* Init step2-4: write QMU MAC address (low, middle then high). */
	ksz8851_reg_write(REG_MAC_ADDR_0, (ETHERNET_CONF_ETHADDR4 << 8) | ETHERNET_CONF_ETHADDR5);
	ksz8851_reg_write(REG_MAC_ADDR_2, (ETHERNET_CONF_ETHADDR2 << 8) | ETHERNET_CONF_ETHADDR3);
	ksz8851_reg_write(REG_MAC_ADDR_4, (ETHERNET_CONF_ETHADDR0 << 8) | ETHERNET_CONF_ETHADDR1);

	/* Init step5: enable QMU Transmit Frame Data Pointer Auto Increment. */
	ksz8851_reg_write(REG_TX_ADDR_PTR, ADDR_PTR_AUTO_INC);

	/* Init step6: configure QMU transmit control register. */
	ksz8851_reg_write(REG_TX_CTRL,
			TX_CTRL_ICMP_CHECKSUM |
			TX_CTRL_UDP_CHECKSUM |
			TX_CTRL_TCP_CHECKSUM |
			TX_CTRL_IP_CHECKSUM |
			TX_CTRL_FLOW_ENABLE |
			TX_CTRL_PAD_ENABLE |
			TX_CTRL_CRC_ENABLE
		);

	/* Init step7: enable QMU Receive Frame Data Pointer Auto Increment. */
	ksz8851_reg_write(REG_RX_ADDR_PTR, ADDR_PTR_AUTO_INC);

	/* Init step8: configure QMU Receive Frame Threshold for one frame. */
	ksz8851_reg_write(REG_RX_FRAME_CNT_THRES, 1);

	/* Init step9: configure QMU receive control register1. */
	ksz8851_reg_write(REG_RX_CTRL1,
			RX_CTRL_UDP_CHECKSUM |
			RX_CTRL_TCP_CHECKSUM |
			RX_CTRL_IP_CHECKSUM |
			RX_CTRL_MAC_FILTER |
			RX_CTRL_FLOW_ENABLE |
			RX_CTRL_BROADCAST |
			RX_CTRL_ALL_MULTICAST|
			RX_CTRL_UNICAST);

	/* Init step10: configure QMU receive control register2. */
	ksz8851_reg_write(REG_RX_CTRL2,
			RX_CTRL_IPV6_UDP_NOCHECKSUM |
			RX_CTRL_UDP_LITE_CHECKSUM |
            RX_CTRL_ICMP_CHECKSUM |
			RX_CTRL_BURST_LEN_FRAME);

	/* Init step11: configure QMU receive queue: trigger INT and auto-dequeue frame. */
	ksz8851_reg_write(REG_RXQ_CMD, RXQ_CMD_CNTL | RXQ_TWOBYTE_OFFSET);

	/* Init step12: adjust SPI data output delay. */
	ksz8851_reg_write(REG_BUS_CLOCK_CTRL, BUS_CLOCK_166 | BUS_CLOCK_DIVIDEDBY_1);

	/* Init step13: restart auto-negotiation. */
	ksz8851_reg_setbits(REG_PORT_CTRL, PORT_AUTO_NEG_RESTART);

	/* Init step13.1: force link in half duplex if auto-negotiation failed. */
	if ((ksz8851_reg_read(REG_PORT_CTRL) & PORT_AUTO_NEG_RESTART) != PORT_AUTO_NEG_RESTART)
	{
		ksz8851_reg_clrbits(REG_PORT_CTRL, PORT_FORCE_FULL_DUPLEX);
	}

	/* Init step14: clear interrupt status. */
	ksz8851_reg_write(REG_INT_STATUS, 0xFFFF);

	/* Init step15: set interrupt mask. */
	ksz8851_reg_write(REG_INT_MASK, INT_RX);

	/* Init step16: enable QMU Transmit. */
	ksz8851_reg_setbits(REG_TX_CTRL, TX_CTRL_ENABLE);

	/* Init step17: enable QMU Receive. */
	ksz8851_reg_setbits(REG_RX_CTRL1, RX_CTRL_ENABLE);

	return 0;
}
コード例 #3
0
ファイル: ksz8851snl.c プロジェクト: unnamet/Repo
void ksz8851snl_set_registers(void)
{
	/* Init step2-4: write QMU MAC address (low, middle then high). */
	ksz8851_reg_write(REG_MAC_ADDR_0, (ETHERNET_CONF_ETHADDR4 << 8) | ETHERNET_CONF_ETHADDR5);
	ksz8851_reg_write(REG_MAC_ADDR_2, (ETHERNET_CONF_ETHADDR2 << 8) | ETHERNET_CONF_ETHADDR3);
	ksz8851_reg_write(REG_MAC_ADDR_4, (ETHERNET_CONF_ETHADDR0 << 8) | ETHERNET_CONF_ETHADDR1);

	/* Init step5: enable QMU Transmit Frame Data Pointer Auto Increment. */
	ksz8851_reg_write(REG_TX_ADDR_PTR, ADDR_PTR_AUTO_INC);

	/* Init step6: configure QMU transmit control register. */
	ksz8851_reg_write(REG_TX_CTRL,
			TX_CTRL_ICMP_CHECKSUM |
			TX_CTRL_UDP_CHECKSUM |
			TX_CTRL_TCP_CHECKSUM |
			TX_CTRL_IP_CHECKSUM |
			TX_CTRL_FLOW_ENABLE |
			TX_CTRL_PAD_ENABLE |
			TX_CTRL_CRC_ENABLE
		);

	/* Init step7: enable QMU Receive Frame Data Pointer Auto Increment. */
	ksz8851_reg_write(REG_RX_ADDR_PTR, ADDR_PTR_AUTO_INC);

	/* Init step8: configure QMU Receive Frame Threshold for one frame. */
	ksz8851_reg_write(REG_RX_FRAME_CNT_THRES, 1);

	/* Init step9: configure QMU receive control register1. */
	ksz8851_reg_write(REG_RX_CTRL1,
			RX_CTRL_UDP_CHECKSUM |
			RX_CTRL_TCP_CHECKSUM |
			RX_CTRL_IP_CHECKSUM |
			RX_CTRL_MAC_FILTER |
			RX_CTRL_FLOW_ENABLE |
			RX_CTRL_BROADCAST |
			RX_CTRL_ALL_MULTICAST|
			RX_CTRL_UNICAST);
//	ksz8851_reg_write(REG_RX_CTRL1,
//			RX_CTRL_UDP_CHECKSUM |
//			RX_CTRL_TCP_CHECKSUM |
//			RX_CTRL_IP_CHECKSUM |
//			RX_CTRL_FLOW_ENABLE |
//			RX_CTRL_PROMISCUOUS);

	ksz8851_reg_write(REG_RX_CTRL2,
			RX_CTRL_IPV6_UDP_NOCHECKSUM |
			RX_CTRL_UDP_LITE_CHECKSUM |
			RX_CTRL_ICMP_CHECKSUM |
			RX_CTRL_BURST_LEN_FRAME);


//#define   RXQ_TWOBYTE_OFFSET          (0x0200)    /* Enable adding 2-byte before frame header for IP aligned with DWORD */
#warning Remember to try the above option to get a 2-byte offset

	/* Init step11: configure QMU receive queue: trigger INT and auto-dequeue frame. */
	ksz8851_reg_write( REG_RXQ_CMD, RXQ_CMD_CNTL | RXQ_TWOBYTE_OFFSET );

	/* Init step12: adjust SPI data output delay. */
	ksz8851_reg_write(REG_BUS_CLOCK_CTRL, BUS_CLOCK_166 | BUS_CLOCK_DIVIDEDBY_1);

	/* Init step13: restart auto-negotiation. */
	ksz8851_reg_setbits(REG_PORT_CTRL, PORT_AUTO_NEG_RESTART);

	/* Init step13.1: force link in half duplex if auto-negotiation failed. */
	if ((ksz8851_reg_read(REG_PORT_CTRL) & PORT_AUTO_NEG_RESTART) != PORT_AUTO_NEG_RESTART)
	{
		ksz8851_reg_clrbits(REG_PORT_CTRL, PORT_FORCE_FULL_DUPLEX);
	}

	/* Init step14: clear interrupt status. */
	ksz8851_reg_write(REG_INT_STATUS, 0xFFFF);

	/* Init step15: set interrupt mask. */
	ksz8851_reg_write(REG_INT_MASK, INT_RX);

	/* Init step16: enable QMU Transmit. */
	ksz8851_reg_setbits(REG_TX_CTRL, TX_CTRL_ENABLE);

	/* Init step17: enable QMU Receive. */
	ksz8851_reg_setbits(REG_RX_CTRL1, RX_CTRL_ENABLE);
}