gadget-kspconsole/unicore-mx/lib/ethernet/mac_lm3s.c
Daniele Lacamera b8a7ffcd31 Initial import
2023-11-27 15:16:45 +01:00

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;
}