163 lines
3.6 KiB
C
163 lines
3.6 KiB
C
#include <string.h>
|
|
#include <stdint.h>
|
|
#include <unicore-mx/ethernet/mac.h>
|
|
#include <unicore-mx/ethernet/phy.h>
|
|
#include <unicore-mx/cm3/nvic.h>
|
|
#include <unicore-mx/cm3/systick.h>
|
|
#include <unicore-mx/lm3s/memorymap.h>
|
|
#include <unicore-mx/lm3s/systemcontrol.h>
|
|
|
|
|
|
#define ETH_IRQMASK_RX (1)
|
|
|
|
void eth_set_mac(uint8_t *mac)
|
|
{
|
|
ETH_MAC_ADDR0 = (mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | (mac[3]);
|
|
ETH_MAC_ADDR1 = (mac[4]<< 24) | (mac[6] << 16);
|
|
}
|
|
|
|
// void eth_desc_init(uint8_t *buf, uint32_t nTx, uint32_t nRx, uint32_t cTx, uint32_t cRx, bool isext);
|
|
|
|
bool eth_tx(uint8_t *ppkt, uint32_t n)
|
|
{
|
|
uint32_t word;
|
|
unsigned int i = 0;
|
|
if (n > (2048 - 2))
|
|
return false;
|
|
|
|
if (ETH_MAC_TR != 0)
|
|
return false;
|
|
|
|
word = ((n - 14) & 0xFFFF);
|
|
word |= (ppkt[i++] << 16);
|
|
word |= (ppkt[i++] << 24);
|
|
ETH_MAC_DATA = word;
|
|
|
|
while (i < (n - 4)) {
|
|
word = ppkt[i++];
|
|
word |= (ppkt[i++] << 8);
|
|
word |= (ppkt[i++] << 16);
|
|
word |= (ppkt[i++] << 24);
|
|
ETH_MAC_DATA = word;
|
|
}
|
|
word = ppkt[i++];
|
|
if (i < n)
|
|
word |= ppkt[i++] << 8;
|
|
if (i < n)
|
|
word |= ppkt[i++] << 16;
|
|
if (i < n)
|
|
word |= ppkt[i++] << 24;
|
|
|
|
ETH_MAC_DATA = word;
|
|
ETH_MAC_TR = 1;
|
|
return true;
|
|
}
|
|
|
|
bool eth_rx(uint8_t *ppkt, uint32_t *len, uint32_t maxlen)
|
|
{
|
|
uint32_t word;
|
|
unsigned int i = 0;
|
|
if ((ETH_MAC_NP & 0x3F) == 0) {
|
|
return false;
|
|
}
|
|
|
|
word = ETH_MAC_DATA;
|
|
*len = (word & 0xFFFF);
|
|
if (maxlen < *len) {
|
|
*len = maxlen;
|
|
}
|
|
|
|
ppkt[i++] = (uint8_t)((word & 0x00FF0000) >> 16);
|
|
ppkt[i++] = (uint8_t)((word & 0xFF000000) >> 24);
|
|
|
|
while(i < (*len - 6)) {
|
|
word = ETH_MAC_DATA;
|
|
ppkt[i++] = (word & 0x000000FF);
|
|
ppkt[i++] = (uint8_t)((word & 0x0000FF00) >> 8);
|
|
ppkt[i++] = (uint8_t)((word & 0x00FF0000) >> 16);
|
|
ppkt[i++] = (uint8_t)((word & 0xFF000000) >> 24);
|
|
}
|
|
word = ETH_MAC_DATA;
|
|
ppkt[i++] = (word & 0x000000FF);
|
|
if (i < *len)
|
|
ppkt[i++] = (uint8_t)((word & 0x0000FF00) >> 8);
|
|
if (i < *len)
|
|
ppkt[i++] = (uint8_t)((word & 0x00FF0000) >> 16);
|
|
if (i < *len)
|
|
ppkt[i++] = (uint8_t)((word & 0xFF000000) >> 24);
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
void eth_enable_checksum_offload(void)
|
|
{
|
|
ETH_MAC_TCTL = ETH_TCTL_CRCGEN;
|
|
ETH_MAC_RCTL = ETH_RCTL_CRCFILTER;
|
|
}
|
|
|
|
|
|
|
|
void eth_init(uint8_t phy, enum eth_clk clock)
|
|
{
|
|
(void)phy;
|
|
/* Enable device */
|
|
SYSTEMCONTROL_SCGC2 |= (SYSCTL_CGR2_ETH_PHY | SYSCTL_CGR2_ETH_MAC);
|
|
/* Reset device */
|
|
SYSTEMCONTROL_SRCR2 |= (SYSCTL_CGR2_ETH_PHY | SYSCTL_CGR2_ETH_MAC);
|
|
|
|
/* Disable interrupts */
|
|
ETH_MAC_IM = 0;
|
|
/* Clear pending IRQs */
|
|
ETH_MAC_RISACK = ETH_INT_ALL;
|
|
|
|
/* Set ethernet clock speed */
|
|
ETH_MAC_MDV = clock;
|
|
|
|
/* Set transmit control register */
|
|
ETH_MAC_TCTL = ETH_TCTL_DUPLEX | ETH_TCTL_PADDING | ETH_TCTL_CRCGEN;
|
|
|
|
/* Set receive control register */
|
|
ETH_MAC_RCTL = ETH_RCTL_MCAST;
|
|
|
|
/* Disable timestamps */
|
|
ETH_MAC_TS = 0;
|
|
|
|
}
|
|
|
|
void eth_start(void) {
|
|
/* Enable Ethernet */
|
|
ETH_MAC_RCTL |= ETH_RCTL_CLRFIFO;
|
|
ETH_MAC_RCTL |= ETH_RCTL_RXON;
|
|
|
|
|
|
ETH_MAC_TCTL |= ETH_TCTL_TXON;
|
|
|
|
|
|
ETH_MAC_RCTL |= ETH_RCTL_CLRFIFO;
|
|
}
|
|
|
|
void eth_irq_enable(uint32_t reason)
|
|
{
|
|
(void)reason;
|
|
ETH_MAC_IM |= reason;
|
|
}
|
|
|
|
void eth_irq_disable(uint32_t reason)
|
|
{
|
|
(void)reason;
|
|
ETH_MAC_IM &= (~reason);
|
|
}
|
|
|
|
bool eth_irq_is_pending(uint32_t reason) {
|
|
if ((ETH_MAC_RISACK & reason) == reason)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool eth_irq_ack_pending(uint32_t reason)
|
|
{
|
|
(void)reason;
|
|
ETH_MAC_RISACK |= reason;
|
|
return false;
|
|
}
|