Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TMS570 support #2935

Merged
merged 1 commit into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
237 changes: 237 additions & 0 deletions mongoose.c
Original file line number Diff line number Diff line change
Expand Up @@ -18507,6 +18507,243 @@ struct mg_tcpip_driver mg_tcpip_driver_tm4c = {mg_tcpip_driver_tm4c_init,
mg_tcpip_driver_tm4c_up};
#endif

#ifdef MG_ENABLE_LINES
#line 1 "src/drivers/tms570.c"
#endif


#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TMS570) && MG_ENABLE_DRIVER_TMS570
struct tms570_emac_ctrl {
volatile uint32_t REVID, SOFTRESET, RESERVED1[1], INTCONTROL, C0RXTHRESHEN,
C0RXEN, C0TXEN, C0MISCEN, RESERVED2[8],
C0RXTHRESHSTAT, C0RXSTAT, C0TXSTAT, C0MISCSTAT,
RESERVED3[8],
C0RXIMAX, C0TXIMAX;
};
struct tms570_emac {
volatile uint32_t TXREVID, TXCONTROL, TXTEARDOWN, RESERVED1[1], RXREVID,
RXCONTROL, RXTEARDOWN, RESERVED2[25], TXINTSTATRAW,TXINTSTATMASKED,
TXINTMASKSET, TXINTMASKCLEAR, MACINVECTOR, MACEOIVECTOR, RESERVED8[2], RXINTSTATRAW,
RXINTSTATMASKED, RXINTMASKSET, RXINTMASKCLEAR, MACINTSTATRAW, MACINTSTATMASKED,
MACINTMASKSET, MACINTMASKCLEAR, RESERVED3[16], RXMBPENABLE, RXUNICASTSET,
RXUNICASTCLEAR, RXMAXLEN, RXBUFFEROFFSET, RXFILTERLOWTHRESH, RESERVED9[2], RXFLOWTHRESH[8],
RXFREEBUFFER[8], MACCONTROL, MACSTATUS, EMCONTROL, FIFOCONTROL, MACCONFIG,
SOFTRESET, RESERVED4[22], MACSRCADDRLO, MACSRCADDRHI, MACHASH1, MACHASH2,
BOFFTEST, TPACETEST, RXPAUSE, TXPAUSE, RESERVED5[4], RXGOODFRAMES, RXBCASTFRAMES,
RXMCASTFRAMES, RXPAUSEFRAMES, RXCRCERRORS, RXALIGNCODEERRORS, RXOVERSIZED,
RXJABBER, RXUNDERSIZED, RXFRAGMENTS, RXFILTERED, RXQOSFILTERED, RXOCTETS,
TXGOODFRAMES, TXBCASTFRAMES, TXMCASTFRAMES, TXPAUSEFRAMES, TXDEFERRED,
TXCOLLISION, TXSINGLECOLL, TXMULTICOLL, TXEXCESSIVECOLL, TXLATECOLL,
TXUNDERRUN, TXCARRIERSENSE, TXOCTETS, FRAME64, FRAME65T127, FRAME128T255,
FRAME256T511, FRAME512T1023, FRAME1024TUP, NETOCTETS, RXSOFOVERRUNS,
RXMOFOVERRUNS, RXDMAOVERRUNS, RESERVED6[156], MACADDRLO, MACADDRHI,
MACINDEX, RESERVED7[61], TXHDP[8], RXHDP[8], TXCP[8], RXCP[8];
};
struct tms570_mdio {
volatile uint32_t REVID, CONTROL, ALIVE, LINK, LINKINTRAW, LINKINTMASKED,
RESERVED1[2], USERINTRAW, USERINTMASKED, USERINTMASKSET, USERINTMASKCLEAR,
RESERVED2[20], USERACCESS0, USERPHYSEL0, USERACCESS1, USERPHYSEL1;
};
#define SWAP32(x) ( (((x) & 0x000000FF) << 24) | \
(((x) & 0x0000FF00) << 8) | \
(((x) & 0x00FF0000) >> 8) | \
(((x) & 0xFF000000) >> 24) )
#undef EMAC
#undef EMAC_CTRL
#undef MDIO
#define EMAC ((struct tms570_emac *) (uintptr_t) 0xFCF78000)
#define EMAC_CTRL ((struct tms570_emac_ctrl *) (uintptr_t) 0xFCF78800)
#define MDIO ((struct tms570_mdio *) (uintptr_t) 0xFCF78900)
#define ETH_PKT_SIZE 1540 // Max frame size
#define ETH_DESC_CNT 4 // Descriptors count
#define ETH_DS 4 // Descriptor size (words)
static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]
__attribute__((section(".ETH_CPPI"), aligned(4))); // TX descriptors
static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]
__attribute__((section(".ETH_CPPI"), aligned(4))); // RX descriptors
static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]
__attribute__((aligned(4))); // RX ethernet buffers
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]
__attribute__((aligned(4))); // TX ethernet buffers
static struct mg_tcpip_if *s_ifp; // MIP interface
static uint16_t emac_read_phy(uint8_t addr, uint8_t reg) {
while(MDIO->USERACCESS0 & MG_BIT(31)) (void) 0;
MDIO->USERACCESS0 = MG_BIT(31) | ((reg & 0x1f) << 21) |
((addr & 0x1f) << 16);
while(MDIO->USERACCESS0 & MG_BIT(31)) (void) 0;
return MDIO->USERACCESS0 & 0xffff;
}
static void emac_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
while(MDIO->USERACCESS0 & MG_BIT(31)) (void) 0;
MDIO->USERACCESS0 = MG_BIT(31) | MG_BIT(30) | ((reg & 0x1f) << 21) |
((addr & 0x1f) << 16) | (val & 0xffff);
while(MDIO->USERACCESS0 & MG_BIT(31)) (void) 0;
}
static bool mg_tcpip_driver_tms570_init(struct mg_tcpip_if *ifp) {
struct mg_tcpip_driver_tms570_data *d =
(struct mg_tcpip_driver_tms570_data *) ifp->driver_data;
s_ifp = ifp;
EMAC_CTRL->SOFTRESET = MG_BIT(0); // Reset the EMAC Control Module
while(EMAC_CTRL->SOFTRESET & MG_BIT(0)) (void) 0; // wait
EMAC->SOFTRESET = MG_BIT(0); // Reset the EMAC Module
while(EMAC->SOFTRESET & MG_BIT(0)) (void) 0;
EMAC->MACCONTROL = 0;
EMAC->RXCONTROL = 0;
EMAC->TXCONTROL = 0;
// Initialize all the header descriptor pointer registers
uint32_t i;
for(i = 0; i < ETH_DESC_CNT; i++) {
EMAC->RXHDP[i] = 0;
EMAC->TXHDP[i] = 0;
EMAC->RXCP[i] = 0;
EMAC->TXCP[i] = 0;
///EMAC->RXFREEBUFFER[i] = 0xff;
}
// Clear the interrupt enable for all the channels
EMAC->TXINTMASKCLEAR = 0xff;
EMAC->RXINTMASKCLEAR = 0xff;
EMAC->MACHASH1 = 0;
EMAC->MACHASH2 = 0;
EMAC->RXBUFFEROFFSET = 0;
EMAC->RXUNICASTCLEAR = 0xff;
EMAC->RXUNICASTSET = 0;
EMAC->RXMBPENABLE = 0;
// init MDIO
// MDIO_CLK frequency = VCLK3/(CLKDIV + 1). (MDIO must be between 1.0 - 2.5Mhz)
uint32_t clkdiv = 75; // VCLK is configured to 75Mhz
// CLKDIV, ENABLE, PREAMBLE, FAULTENB
MDIO->CONTROL = (clkdiv - 1) | MG_BIT(30) | MG_BIT(20) | MG_BIT(18);
volatile int delay = 0xfff;
while (delay-- != 0) (void) 0;
struct mg_phy phy = {emac_read_phy, emac_write_phy};
mg_phy_init(&phy, d->phy_addr, MG_PHY_CLOCKS_MAC);
// set the mac address
EMAC->MACSRCADDRHI = ifp->mac[0] | (ifp->mac[1] << 8) | (ifp->mac[2] << 16) |
(ifp->mac[3] << 24);
EMAC->MACSRCADDRLO = ifp->mac[4] | (ifp->mac[5] << 8);
uint32_t channel;
for (channel = 0; channel < 8; channel++) {
EMAC->MACINDEX = channel;
EMAC->MACADDRHI = ifp->mac[0] | (ifp->mac[1] << 8) | (ifp->mac[2] << 16) |
(ifp->mac[3] << 24);
EMAC->MACADDRLO = ifp->mac[4] | (ifp->mac[5] << 8) | MG_BIT(20) |
MG_BIT(19) | (channel << 16);
}
EMAC->RXUNICASTSET = 1; // accept unicast frames;
EMAC->RXMBPENABLE = MG_BIT(30) | MG_BIT(13); // CRC, broadcast;

// Initialize the descriptors
for (i = 0; i < ETH_DESC_CNT; i++) {
if (i < ETH_DESC_CNT - 1) {
s_txdesc[i][0] = 0;
s_rxdesc[i][0] = SWAP32(((uint32_t) &s_rxdesc[i + 1][0]));
}
s_txdesc[i][1] = SWAP32(((uint32_t) s_txbuf[i]));
s_rxdesc[i][1] = SWAP32(((uint32_t) s_rxbuf[i]));
s_txdesc[i][2] = 0;
s_rxdesc[i][2] = SWAP32(ETH_PKT_SIZE);
s_txdesc[i][3] = 0;
s_rxdesc[i][3] = SWAP32(MG_BIT(29)); // OWN
}
s_txdesc[ETH_DESC_CNT - 1][0] = 0;
s_rxdesc[ETH_DESC_CNT - 1][0] = 0;

EMAC->MACCONTROL = MG_BIT(5) | MG_BIT(0); // Enable MII, Full-duplex
//EMAC->TXINTMASKSET = 1; // Enable TX interrupt
EMAC->RXINTMASKSET = 1; // Enable RX interrupt
//EMAC_CTRL->C0TXEN = 1; // TX completion interrupt
EMAC_CTRL->C0RXEN = 1; // RX completion interrupt
EMAC->TXCONTROL = 1; // TXEN
EMAC->RXCONTROL = 1; // RXEN
EMAC->RXHDP[0] = (uint32_t) &s_rxdesc[0][0];
return true;
}
static uint32_t s_txno;
static size_t mg_tcpip_driver_tms570_tx(const void *buf, size_t len,
struct mg_tcpip_if *ifp) {
if (len > sizeof(s_txbuf[s_txno])) {
MG_ERROR(("Frame too big, %ld", (long) len));
len = 0; // fail
} else if ((s_txdesc[s_txno][3] & SWAP32(MG_BIT(29)))) {
ifp->nerr++;
MG_ERROR(("No descriptors available"));
len = 0; // fail
} else {
memcpy(s_txbuf[s_txno], buf, len); // Copy data
if (len < 128) len = 128;
s_txdesc[s_txno][2] = SWAP32((uint32_t) len); // Set data len
s_txdesc[s_txno][3] =
SWAP32(MG_BIT(31) | MG_BIT(30) | MG_BIT(29) | len); // SOP, EOP, OWN, length

while(EMAC->TXHDP[0] != 0) (void) 0;
EMAC->TXHDP[0] = (uint32_t) &s_txdesc[s_txno][0];
if(++s_txno == ETH_DESC_CNT) {
s_txno = 0;
}
}
return len;
(void) ifp;
}
static bool mg_tcpip_driver_tms570_up(struct mg_tcpip_if *ifp) {
struct mg_tcpip_driver_tms570_data *d =
(struct mg_tcpip_driver_tms570_data *) ifp->driver_data;
uint8_t speed = MG_PHY_SPEED_10M;
bool up = false, full_duplex = false;
struct mg_phy phy = {emac_read_phy, emac_write_phy};
up = mg_phy_up(&phy, d->phy_addr, &full_duplex, &speed);
if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) {
// link state just went up
MG_DEBUG(("Link is %uM %s-duplex", speed == MG_PHY_SPEED_10M ? 10 : 100,
full_duplex ? "full" : "half"));
}
return up;
}
#pragma CODE_STATE(EMAC_TX_IRQHandler, 32)
#pragma INTERRUPT(EMAC_TX_IRQHandler, IRQ)
void EMAC_TX_IRQHandler(void) {
uint32_t status = EMAC_CTRL->C0TXSTAT;
if (status & 1) { // interrupt caused on channel 0
while(s_txdesc[s_txno][3] & SWAP32(MG_BIT(29))) (void) 0;
EMAC->TXCP[0] = (uint32_t) &s_txdesc[s_txno][0];
}
//Write the DMA end of interrupt vector
EMAC->MACEOIVECTOR = 2;
}
static uint32_t s_rxno;
#pragma CODE_STATE(EMAC_RX_IRQHandler, 32)
#pragma INTERRUPT(EMAC_RX_IRQHandler, IRQ)
void EMAC_RX_IRQHandler(void) {
uint32_t status = EMAC_CTRL->C0RXSTAT;
if (status & 1) { // Frame received, loop
uint32_t i;
//MG_INFO(("RX interrupt"));
for (i = 0; i < 10; i++) { // read as they arrive but not forever
if ((s_rxdesc[s_rxno][3] & SWAP32(MG_BIT(29))) == 0) {
uint32_t len = SWAP32(s_rxdesc[s_rxno][3]) & 0xffff;
//MG_INFO(("recv len: %d", len));
//mg_hexdump(s_rxbuf[s_rxno], len);
mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
uint32_t flags = s_rxdesc[s_rxno][3];
s_rxdesc[s_rxno][3] = SWAP32(MG_BIT(29));
s_rxdesc[s_rxno][2] = SWAP32(ETH_PKT_SIZE);
EMAC->RXCP[0] = (uint32_t) &s_rxdesc[s_rxno][0];
if (flags & SWAP32(MG_BIT(28))) {
//MG_INFO(("EOQ detected"));
EMAC->RXHDP[0] = (uint32_t) &s_rxdesc[0][0];
}
}
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
}
}
//Write the DMA end of interrupt vector
EMAC->MACEOIVECTOR = 1;
}
struct mg_tcpip_driver mg_tcpip_driver_tms570 = {mg_tcpip_driver_tms570_init,
mg_tcpip_driver_tms570_tx, NULL,
mg_tcpip_driver_tms570_up};
#endif


#ifdef MG_ENABLE_LINES
#line 1 "src/drivers/w5500.c"
#endif
Expand Down
34 changes: 34 additions & 0 deletions mongoose.h
Original file line number Diff line number Diff line change
Expand Up @@ -2786,6 +2786,7 @@ void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp);
extern struct mg_tcpip_driver mg_tcpip_driver_stm32f;
extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
extern struct mg_tcpip_driver mg_tcpip_driver_tms570;
extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
extern struct mg_tcpip_driver mg_tcpip_driver_imxrt;
extern struct mg_tcpip_driver mg_tcpip_driver_same54;
Expand Down Expand Up @@ -3124,6 +3125,39 @@ struct mg_tcpip_driver_tm4c_data {
#endif


#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TMS570) && MG_ENABLE_DRIVER_TMS570
struct mg_tcpip_driver_tms570_data {
int mdc_cr;
int phy_addr;
};

#ifndef MG_TCPIP_PHY_ADDR
#define MG_TCPIP_PHY_ADDR 0
#endif

#ifndef MG_DRIVER_MDC_CR
#define MG_DRIVER_MDC_CR 1
#endif

#define MG_TCPIP_DRIVER_INIT(mgr) \
do { \
static struct mg_tcpip_driver_tms570_data driver_data_; \
static struct mg_tcpip_if mif_; \
driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
mif_.ip = MG_TCPIP_IP; \
mif_.mask = MG_TCPIP_MASK; \
mif_.gw = MG_TCPIP_GW; \
mif_.driver = &mg_tcpip_driver_tms570; \
mif_.driver_data = &driver_data_; \
MG_SET_MAC_ADDRESS(mif_.mac); \
mg_tcpip_init(mgr, &mif_); \
MG_INFO(("Driver: tms570, MAC: %M", mg_print_mac, mif_.mac));\
} while (0)
#endif



#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC

struct mg_tcpip_driver_xmc_data {
Expand Down
Loading
Loading