diff options
| author | bluebear233 <417350690.qq.com> | 2017-12-31 20:28:34 +0800 |
|---|---|---|
| committer | bluebear233 <417350690.qq.com> | 2017-12-31 20:28:34 +0800 |
| commit | bf6726aeec678c4e0f43ce0919b55867d9806d3e (patch) | |
| tree | c8529fb86c5c5f05b6d3e5f219b10a27e2621918 /bsp | |
| parent | 8a923193ab6af396cb58ebb48eecaba9e4e689ee (diff) | |
[BSP]NUC472 增加网络驱动
Diffstat (limited to 'bsp')
| -rw-r--r-- | bsp/nuvoton_nuc472/Libraries/StdDriver/src/sys_.c (renamed from bsp/nuvoton_nuc472/Libraries/StdDriver/src/sys.c) | 0 | ||||
| -rw-r--r-- | bsp/nuvoton_nuc472/applications/application.c | 9 | ||||
| -rw-r--r-- | bsp/nuvoton_nuc472/drivers/nuc472_eth.c | 519 | ||||
| -rw-r--r-- | bsp/nuvoton_nuc472/drivers/nuc472_eth.h | 127 | ||||
| -rw-r--r-- | bsp/nuvoton_nuc472/project.ewp | 128 | ||||
| -rw-r--r-- | bsp/nuvoton_nuc472/project.uvprojx | 268 | ||||
| -rw-r--r-- | bsp/nuvoton_nuc472/rtconfig.h | 23 | ||||
| -rw-r--r-- | bsp/nuvoton_nuc472/rtconfig.py | 2 |
8 files changed, 1054 insertions, 22 deletions
diff --git a/bsp/nuvoton_nuc472/Libraries/StdDriver/src/sys.c b/bsp/nuvoton_nuc472/Libraries/StdDriver/src/sys_.c index ec6c2410f4..ec6c2410f4 100644 --- a/bsp/nuvoton_nuc472/Libraries/StdDriver/src/sys.c +++ b/bsp/nuvoton_nuc472/Libraries/StdDriver/src/sys_.c diff --git a/bsp/nuvoton_nuc472/applications/application.c b/bsp/nuvoton_nuc472/applications/application.c index f7948001c7..5ab3c31df4 100644 --- a/bsp/nuvoton_nuc472/applications/application.c +++ b/bsp/nuvoton_nuc472/applications/application.c @@ -15,7 +15,14 @@ int main(void) { - while(1){ +#ifdef RT_USING_LWIP + /* initialize eth interface */ + extern void rt_hw_nuc472_emac_init(void); + rt_hw_nuc472_emac_init(); +#endif /* RT_USING_LWIP */ + + while(1) + { rt_thread_delay(RT_TICK_PER_SECOND); } } diff --git a/bsp/nuvoton_nuc472/drivers/nuc472_eth.c b/bsp/nuvoton_nuc472/drivers/nuc472_eth.c new file mode 100644 index 0000000000..de9f32eedd --- /dev/null +++ b/bsp/nuvoton_nuc472/drivers/nuc472_eth.c @@ -0,0 +1,519 @@ +/* + * Copyright (c) 2013 Nuvoton Technology Corp. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: NUC472 MAC driver source file + */ + +#include <rtconfig.h> + +#ifdef RT_USING_LWIP +#include <rtthread.h> +#include "nuc472_eth.h" +#include <netif/ethernetif.h> +#include <netif/etharp.h> +#include <lwip/icmp.h> +#include "lwipopts.h" + +#define ETH_TRIGGER_RX() EMAC->RXST = 0 +#define ETH_TRIGGER_TX() EMAC->TXST = 0 +#define ETH_ENABLE_TX() EMAC->CTL |= EMAC_CTL_TXON +#define ETH_ENABLE_RX() EMAC->CTL |= EMAC_CTL_RXON +#define ETH_DISABLE_TX() EMAC->CTL &= ~EMAC_CTL_TXON +#define ETH_DISABLE_RX() EMAC->CTL &= ~EMAC_CTL_RXON + +rt_uint8_t ethaddr[] = {0x00, 0x00, 0x00, 0x59, 0x16, 0x88}; + +struct rt_nuc472_emac +{ + struct eth_device parent; + + EMAC_T *emac_base; + + rt_uint8_t dev_addr[6]; + struct eth_descriptor volatile *cur_tx_desc_ptr, *cur_rx_desc_ptr, *fin_tx_desc_ptr; + + struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM]; + struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM]; + rt_uint8_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE]; + rt_uint8_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE]; +}; +typedef struct rt_nuc472_emac* rt_nuc472_emac_t; +struct rt_nuc472_emac nuc472_emac_device; + +static void mdio_write(rt_nuc472_emac_t emac, rt_uint8_t addr, rt_uint8_t reg, rt_uint16_t val) +{ + EMAC_T *emac_base = emac->emac_base; + + emac_base->MIIMDAT = val; + emac_base->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_WRITE_Msk | EMAC_MIIMCTL_MDCON_Msk; + + while (emac_base->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk); + +} + +static rt_uint16_t mdio_read(rt_nuc472_emac_t emac, rt_uint8_t addr, rt_uint8_t reg) +{ + EMAC_T *emac_base = emac->emac_base; + + emac_base->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_MDCON_Msk; + while (emac_base->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk); + + return(emac_base->MIIMDAT); +} + +static int reset_phy(rt_nuc472_emac_t emac) +{ + rt_uint16_t reg; + rt_uint32_t delay; + EMAC_T *emac_base = emac->emac_base; + + mdio_write(emac, CONFIG_PHY_ADDR, MII_BMCR, BMCR_RESET); + + delay = 2000; + while(delay-- > 0) + { + if((mdio_read(emac, CONFIG_PHY_ADDR, MII_BMCR) & BMCR_RESET) == 0) + break; + } + + if(delay == 0) + { + rt_kprintf("Reset phy failed\n"); + return(-1); + } + + mdio_write(emac, CONFIG_PHY_ADDR, MII_ADVERTISE, ADVERTISE_CSMA | + ADVERTISE_10HALF | + ADVERTISE_10FULL | + ADVERTISE_100HALF | + ADVERTISE_100FULL); + + reg = mdio_read(emac, CONFIG_PHY_ADDR, MII_BMCR); + mdio_write(emac, CONFIG_PHY_ADDR, MII_BMCR, reg | BMCR_ANRESTART); + + delay = 200000; + while(delay-- > 0) + { + if((mdio_read(emac, CONFIG_PHY_ADDR, MII_BMSR) & (BMSR_ANEGCOMPLETE | BMSR_LSTATUS)) + == (BMSR_ANEGCOMPLETE | BMSR_LSTATUS)) + break; + } + + if(delay == 0) + { + rt_kprintf("AN failed. Set to 100 FULL\n"); + emac_base->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk); + return(-1); + } + else + { + reg = mdio_read(emac, CONFIG_PHY_ADDR, MII_LPA); + + if(reg & ADVERTISE_100FULL) + { + rt_kprintf("100 full\n"); + emac_base->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk); + } + else if(reg & ADVERTISE_100HALF) + { + rt_kprintf("100 half\n"); + emac_base->CTL = (EMAC->CTL & ~EMAC_CTL_FUDUP_Msk) | EMAC_CTL_OPMODE_Msk; + } + else if(reg & ADVERTISE_10FULL) + { + rt_kprintf("10 full\n"); + emac_base->CTL = (EMAC->CTL & ~EMAC_CTL_OPMODE_Msk) | EMAC_CTL_FUDUP_Msk; + } else + { + rt_kprintf("10 half\n"); + emac_base->CTL &= ~(EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk); + } + } + + return(0); +} + +static void init_tx_desc(rt_nuc472_emac_t emac) +{ + EMAC_T *emac_base = emac->emac_base; + rt_uint32_t i; + + emac->cur_tx_desc_ptr = emac->fin_tx_desc_ptr = &emac->tx_desc[0]; + + for(i = 0; i < TX_DESCRIPTOR_NUM; i++) + { + emac->tx_desc[i].status1 = TXFD_PADEN | TXFD_CRCAPP | TXFD_INTEN; + emac->tx_desc[i].buf = &emac->tx_buf[i][0]; + emac->tx_desc[i].status2 = 0; + emac->tx_desc[i].next = &emac->tx_desc[(i + 1) % TX_DESCRIPTOR_NUM]; + } + emac_base->TXDSA = (unsigned int)&emac->tx_desc[0]; + return; +} + +static void init_rx_desc(rt_nuc472_emac_t emac) +{ + EMAC_T *emac_base = emac->emac_base; + rt_uint32_t i; + + emac->cur_rx_desc_ptr = &emac->rx_desc[0]; + + for(i = 0; i < RX_DESCRIPTOR_NUM; i++) + { + emac->rx_desc[i].status1 = OWNERSHIP_EMAC; + emac->rx_desc[i].buf = &emac->rx_buf[i][0]; + emac->rx_desc[i].status2 = 0; + emac->rx_desc[i].next = &emac->rx_desc[(i + 1) % TX_DESCRIPTOR_NUM]; + } + emac_base->RXDSA = (unsigned int)&emac->rx_desc[0]; + return; +} + +static void set_mac_addr(rt_nuc472_emac_t emac, rt_uint8_t *addr) +{ + EMAC_T *emac_base = emac->emac_base; + + emac_base->CAM0M = (addr[0] << 24) | + (addr[1] << 16) | + (addr[2] << 8) | + addr[3]; + + emac_base->CAM0L = (addr[4] << 24) | + (addr[5] << 16); + + emac_base->CAMCTL = EMAC_CAMCTL_CMPEN_Msk | EMAC_CAMCTL_AMP_Msk | EMAC_CAMCTL_ABP_Msk; + emac_base->CAMEN = 1; // Enable CAM entry 0 +} + +void EMAC_init(rt_nuc472_emac_t emac, rt_uint8_t *mac_addr) +{ + RT_ASSERT(emac->dev_addr != RT_NULL); + EMAC_T *emac_base = emac->emac_base; + + CLK_EnableModuleClock(EMAC_MODULE); + + // Configure MDC clock rate to HCLK / (127 + 1) = 656 kHz if system is running at 84 MHz + CLK_SetModuleClock(EMAC_MODULE, 0, CLK_CLKDIV3_EMAC(127)); + + // Configure RMII pins + SYS->GPC_MFPL = SYS_GPC_MFPL_PC0MFP_EMAC_REFCLK | + SYS_GPC_MFPL_PC1MFP_EMAC_MII_RXERR | + SYS_GPC_MFPL_PC2MFP_EMAC_MII_RXDV | + SYS_GPC_MFPL_PC3MFP_EMAC_MII_RXD1 | + SYS_GPC_MFPL_PC4MFP_EMAC_MII_RXD0 | + SYS_GPC_MFPL_PC6MFP_EMAC_MII_TXD0 | + SYS_GPC_MFPL_PC7MFP_EMAC_MII_TXD1; + + SYS->GPC_MFPH = SYS_GPC_MFPH_PC8MFP_EMAC_MII_TXEN; + // Enable high slew rate on all RMII pins + PC->SLEWCTL |= 0x1DF; + + // Configure MDC, MDIO at PB14 & PB15 + SYS->GPB_MFPH = SYS_GPB_MFPH_PB14MFP_EMAC_MII_MDC | SYS_GPB_MFPH_PB15MFP_EMAC_MII_MDIO; + + // Reset MAC + emac_base->CTL = EMAC_CTL_RST_Msk; + + init_tx_desc(emac); + init_rx_desc(emac); + + set_mac_addr(emac, mac_addr); // need to reconfigure hardware address 'cos we just RESET emc... + reset_phy(emac); + + emac_base->CTL |= EMAC_CTL_STRIPCRC_Msk | EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk | EMAC_CTL_RMIIEN_Msk | EMAC_CTL_RMIIRXCTL_Msk; + emac_base->INTEN |= EMAC_INTEN_RXIEN_Msk | + EMAC_INTEN_RXGDIEN_Msk | + EMAC_INTEN_RDUIEN_Msk | + EMAC_INTEN_RXBEIEN_Msk | + EMAC_INTEN_TXIEN_Msk | + EMAC_INTEN_TXABTIEN_Msk | + EMAC_INTEN_TXCPIEN_Msk | + EMAC_INTEN_TXBEIEN_Msk; + emac_base->RXST = 0; // trigger Rx + + //NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); + NVIC_SetPriority(EMAC_TX_IRQn, 0); + NVIC_EnableIRQ(EMAC_TX_IRQn); + NVIC_SetPriority(EMAC_RX_IRQn, 1); + NVIC_EnableIRQ(EMAC_RX_IRQn); +} + +void ETH_halt(rt_nuc472_emac_t emac) +{ + EMAC_T *emac_base = emac->emac_base; + + emac_base->CTL &= ~(EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk); +} + +void emac_emac_done(rt_nuc472_emac_t emac) +{ + EMAC_T *emac_base = emac->emac_base; + unsigned int status; + + status = emac_base->INTSTS & 0xFFFF0000; + emac_base->INTSTS = status; + if(status & EMAC_INTSTS_TSALMIF_Msk) + { + // TODO: time stamp alarm. write me!! + } + if(status & EMAC_INTSTS_TXBEIF_Msk) + { + // Shouldn't goes here, unless descriptor corrupted + return; + } +} + +rt_uint8_t *emac_get_tx_buf(rt_nuc472_emac_t emac) +{ + if(emac->cur_tx_desc_ptr->status1 & OWNERSHIP_EMAC) + { + return(RT_NULL); + } + else + { + return(emac->cur_tx_desc_ptr->buf); + } +} + +void ETH_trigger_tx(rt_nuc472_emac_t emac, rt_uint16_t length) +{ + struct eth_descriptor volatile *desc; + + emac->cur_tx_desc_ptr->status2 = (unsigned int)length; + desc = emac->cur_tx_desc_ptr->next; // in case TX is transmitting and overwrite next pointer before we can update cur_tx_desc_ptr + emac->cur_tx_desc_ptr->status1 |= OWNERSHIP_EMAC; + emac->cur_tx_desc_ptr = desc; + + ETH_TRIGGER_TX(); +} + +/* + * NUC472 EMAC Driver for RT-Thread + * Change Logs: + * Date Author Notes + * 2017-12-31 Bluebear233 first implementation + */ +void rt_nuc472_emac_tx_isr(rt_nuc472_emac_t emac) +{ + emac_emac_done(emac); +} + +void rt_nuc472_emac_rx_isr(rt_nuc472_emac_t emac) +{ + EMAC_T *emac_base = emac->emac_base; + + unsigned int status = emac_base->INTSTS & 0xFFFF; + emac_base->INTSTS = status; + + eth_device_ready(&emac->parent); +} + +void EMAC_TX_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + rt_nuc472_emac_tx_isr(&nuc472_emac_device); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +void EMAC_RX_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + rt_nuc472_emac_rx_isr(&nuc472_emac_device); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +static rt_err_t rt_nuc472_emac_init(rt_device_t dev) +{ + rt_nuc472_emac_t emac = (rt_nuc472_emac_t)dev; + + EMAC_init(emac, emac->dev_addr); + +#if LWIP_IPV4 && LWIP_IGMP + netif_set_igmp_mac_filter(stm32_eth->parent.netif, igmp_mac_filter); +#endif /* LWIP_IPV4 && LWIP_IGMP */ + + return RT_EOK; +} + +static rt_err_t rt_nuc472_emac_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_err_t rt_nuc472_emac_close(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_size_t rt_nuc472_emac_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) +{ + rt_set_errno(-RT_ENOSYS); + return 0; +} + +static rt_size_t rt_nuc472_emac_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +{ + rt_set_errno(-RT_ENOSYS); + return 0; +} + +static rt_err_t rt_nuc472_emac_control(rt_device_t dev, int cmd, void *args) +{ + rt_nuc472_emac_t emac = (rt_nuc472_emac_t)dev; + + switch(cmd) + { + case NIOCTL_GADDR: + /* get mac address */ + if(args) rt_memcpy(args, emac->dev_addr, 6); + else return -RT_ERROR; + break; + + default : + break; + } + + return RT_EOK; +} + +rt_err_t rt_nuc472_emac_tx(rt_device_t dev, struct pbuf* p) +{ + rt_nuc472_emac_t emac = (rt_nuc472_emac_t)dev; + struct pbuf* q; + rt_uint32_t offset; + rt_uint8_t *buf = emac_get_tx_buf(emac); + + /* get free tx buffer */ + if(buf == RT_NULL) + { + rt_kprintf("none tx buf\n"); + return -RT_ERROR; + } + + offset = 0; + for (q = p; q != NULL; q = q->next) + { + rt_uint8_t* ptr; + rt_uint32_t len; + + len = q->len; + ptr = q->payload; + + /* Copy the frame to be sent into memory pointed by the current ETHERNET DMA Tx descriptor */ + while (len) + { + buf[offset] = *ptr; + + offset ++; + ptr ++; + len --; + } + } + + ETH_trigger_tx(emac, offset); + + /* Return SUCCESS */ + return RT_EOK; +} + +struct pbuf *rt_nuc472_emac_rx(rt_device_t dev) +{ + rt_nuc472_emac_t emac = (rt_nuc472_emac_t)dev; + struct pbuf* p; + + /* init p pointer */ + p = RT_NULL; + + unsigned int status; + status = emac->cur_rx_desc_ptr->status1; + + if(status & OWNERSHIP_EMAC) + { + goto end; + } + + if (status & RXFD_RXGD) + { + //ethernetif_input(status & 0xFFFF, cur_rx_desc_ptr->buf, cur_rx_desc_ptr->status2, (u32_t)cur_rx_desc_ptr->next); + /* allocate buffer */ + p = pbuf_alloc(PBUF_LINK, status & 0xFFFF, PBUF_RAM); + if (p != RT_NULL) + { + const char * from; + struct pbuf* q; + + from = (const char *)(emac->cur_rx_desc_ptr->buf); + + for (q = p; q != RT_NULL; q = q->next) + { + /* Copy the received frame into buffer from memory pointed by the current ETHERNET DMA Rx descriptor */ + memcpy(q->payload, from, q->len); + from += q->len; + } + } + } + + emac->cur_rx_desc_ptr->status1 = OWNERSHIP_EMAC; + emac->cur_rx_desc_ptr = emac->cur_rx_desc_ptr->next; + + return p; + + end: + ETH_TRIGGER_RX(); + + return p; +} + +static void rt_hw_nuc472_emac_register(rt_nuc472_emac_t emac, char *dev_name, EMAC_T *emac_base, rt_uint8_t *mac_addr) +{ + emac->emac_base = emac_base; + + rt_memcpy(emac->dev_addr, mac_addr, sizeof(emac->dev_addr)); + + emac->parent.parent.init = rt_nuc472_emac_init; + emac->parent.parent.open = rt_nuc472_emac_open; + emac->parent.parent.close = rt_nuc472_emac_close; + emac->parent.parent.read = rt_nuc472_emac_read; + emac->parent.parent.write = rt_nuc472_emac_write; + emac->parent.parent.control = rt_nuc472_emac_control; + emac->parent.parent.user_data = RT_NULL; + + emac->parent.eth_rx = rt_nuc472_emac_rx; + emac->parent.eth_tx = rt_nuc472_emac_tx; + + /* register eth device */ + eth_device_init(&(emac->parent), dev_name); +} + +void rt_hw_nuc472_emac_init(void) +{ + rt_hw_nuc472_emac_register(&nuc472_emac_device, "eh0", EMAC, ethaddr); +} + +#endif diff --git a/bsp/nuvoton_nuc472/drivers/nuc472_eth.h b/bsp/nuvoton_nuc472/drivers/nuc472_eth.h new file mode 100644 index 0000000000..83ded859d6 --- /dev/null +++ b/bsp/nuvoton_nuc472/drivers/nuc472_eth.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013 Nuvoton Technology Corp. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: NUC472 EMAC driver header file + */ +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "NUC472_442.h" +#ifndef _NUC472_ETH_ +#define _NUC472_ETH_ + +/* Generic MII registers. */ + +#define MII_BMCR 0x00 /* Basic mode control register */ +#define MII_BMSR 0x01 /* Basic mode status register */ +#define MII_PHYSID1 0x02 /* PHYS ID 1 */ +#define MII_PHYSID2 0x03 /* PHYS ID 2 */ +#define MII_ADVERTISE 0x04 /* Advertisement control reg */ +#define MII_LPA 0x05 /* Link partner ability reg */ +#define MII_EXPANSION 0x06 /* Expansion register */ +#define MII_DCOUNTER 0x12 /* Disconnect counter */ +#define MII_FCSCOUNTER 0x13 /* False carrier counter */ +#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ +#define MII_RERRCOUNTER 0x15 /* Receive error counter */ +#define MII_SREVISION 0x16 /* Silicon revision */ +#define MII_RESV1 0x17 /* Reserved... */ +#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ +#define MII_PHYADDR 0x19 /* PHY address */ +#define MII_RESV2 0x1a /* Reserved... */ +#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */ +#define MII_NCONFIG 0x1c /* Network interface config */ + +/* Basic mode control register. */ +#define BMCR_RESV 0x007f /* Unused... */ +#define BMCR_CTST 0x0080 /* Collision test */ +#define BMCR_FULLDPLX 0x0100 /* Full duplex */ +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ +#define BMCR_RESET 0x8000 /* Reset the DP83840 */ + +/* Basic mode status register. */ +#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ +#define BMSR_JCD 0x0002 /* Jabber detected */ +#define BMSR_LSTATUS 0x0004 /* Link status */ +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ +#define BMSR_RFAULT 0x0010 /* Remote fault detected */ +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ +#define BMSR_RESV 0x07c0 /* Unused... */ +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ +#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ + +/* Advertisement control register. */ +#define ADVERTISE_SLCT 0x001f /* Selector bits */ +#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ +#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ +#define ADVERTISE_RESV 0x1c00 /* Unused... */ +#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ +#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ +#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ + +#define RX_DESCRIPTOR_NUM 4 // Max Number of Rx Frame Descriptors +#define TX_DESCRIPTOR_NUM 2 // Max number of Tx Frame Descriptors + +#define PACKET_BUFFER_SIZE 1520 + +#define CONFIG_PHY_ADDR 1 + + +// Frame Descriptor's Owner bit +#define OWNERSHIP_EMAC 0x80000000 // 1 = EMAC +//#define OWNERSHIP_CPU 0x7fffffff // 0 = CPU + + + +// Rx Frame Descriptor Status +#define RXFD_RXGD 0x00100000 // Receiving Good Packet Received +#define RXFD_RTSAS 0x00800000 // RX Time Stamp Available + + +// Tx Frame Descriptor's Control bits +#define TXFD_TTSEN 0x08 // Tx Time Stamp Enable +#define TXFD_INTEN 0x04 // Interrupt Enable +#define TXFD_CRCAPP 0x02 // Append CRC +#define TXFD_PADEN 0x01 // Padding Enable + +// Tx Frame Descriptor Status +#define TXFD_TXCP 0x00080000 // Transmission Completion +#define TXFD_TTSAS 0x08000000 // TX Time Stamp Available + +// Tx/Rx buffer descriptor structure +struct eth_descriptor { + u32_t status1; + u8_t *buf; + u32_t status2; + struct eth_descriptor *next; +}; + +#endif /* _NUC472_ETH_ */ diff --git a/bsp/nuvoton_nuc472/project.ewp b/bsp/nuvoton_nuc472/project.ewp index 366030b166..c9216fc601 100644 --- a/bsp/nuvoton_nuc472/project.ewp +++ b/bsp/nuvoton_nuc472/project.ewp @@ -292,16 +292,22 @@ <option> <name>CCIncludePath2</name> <state /> + <state>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\include\ipv4</state> <state>$PROJ_DIR$\Libraries\CMSIS\Include</state> + <state>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\include</state> <state>$PROJ_DIR$\..\..\include</state> <state>$PROJ_DIR$\drivers</state> + <state>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src</state> <state>$PROJ_DIR$\.</state> <state>$PROJ_DIR$\applications</state> <state>$PROJ_DIR$\..\..\libcpu\arm\cortex-m4</state> + <state>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\include\netif</state> <state>$PROJ_DIR$\..\..\components\drivers\include</state> <state>$PROJ_DIR$\..\..\libcpu\arm\common</state> <state>$PROJ_DIR$\Libraries\StdDriver\inc</state> <state>$PROJ_DIR$\..\..\components\finsh</state> + <state>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\include\posix</state> + <state>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\arch\include</state> <state>$PROJ_DIR$\Libraries\Device\Nuvoton\NUC472_442\Include</state> </option> <option> @@ -1209,16 +1215,22 @@ <option> <name>CCIncludePath2</name> <state /> + <state>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\include\ipv4</state> <state>$PROJ_DIR$\Libraries\CMSIS\Include</state> + <state>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\include</state> <state>$PROJ_DIR$\..\..\include</state> <state>$PROJ_DIR$\drivers</state> + <state>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src</state> <state>$PROJ_DIR$\.</state> <state>$PROJ_DIR$\applications</state> <state>$PROJ_DIR$\..\..\libcpu\arm\cortex-m4</state> + <state>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\include\netif</state> <state>$PROJ_DIR$\..\..\components\drivers\include</state> <state>$PROJ_DIR$\..\..\libcpu\arm\common</state> <state>$PROJ_DIR$\Libraries\StdDriver\inc</state> <state>$PROJ_DIR$\..\..\components\finsh</state> + <state>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\include\posix</state> + <state>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\arch\include</state> <state>$PROJ_DIR$\Libraries\Device\Nuvoton\NUC472_442\Include</state> </option> <option> @@ -1846,6 +1858,9 @@ <name>$PROJ_DIR$\drivers\board.c</name> </file> <file> + <name>$PROJ_DIR$\drivers\nuc472_eth.c</name> + </file> + <file> <name>$PROJ_DIR$\drivers\usart.c</name> </file> </group> @@ -1930,7 +1945,7 @@ <name>$PROJ_DIR$\Libraries\StdDriver\src\spi.c</name> </file> <file> - <name>$PROJ_DIR$\Libraries\StdDriver\src\sys.c</name> + <name>$PROJ_DIR$\Libraries\StdDriver\src\sys_.c</name> </file> <file> <name>$PROJ_DIR$\Libraries\StdDriver\src\timer_.c</name> @@ -2056,4 +2071,115 @@ <name>$PROJ_DIR$\..\..\components\finsh\msh_file.c</name> </file> </group> + <group> + <name>lwIP</name> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\arch\sys_arch.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\api\api_lib.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\api\api_msg.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\api\err.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\api\netbuf.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\api\netdb.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\api\netifapi.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\api\sockets.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\api\tcpip.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\def.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\dns.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\inet_chksum.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\init.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\ip.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\memp.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\netif.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\pbuf.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\raw.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\stats.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\sys.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\tcp.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\tcp_in.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\tcp_out.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\timeouts.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\udp.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\netif\ethernet.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\netif\ethernetif.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\netif\lowpan6.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\ipv4\autoip.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\ipv4\dhcp.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\ipv4\etharp.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\ipv4\icmp.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\ipv4\igmp.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\ipv4\ip4.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\ipv4\ip4_addr.c</name> + </file> + <file> + <name>$PROJ_DIR$\..\..\components\net\lwip-2.0.2\src\core\ipv4\ip4_frag.c</name> + </file> + </group> </project> diff --git a/bsp/nuvoton_nuc472/project.uvprojx b/bsp/nuvoton_nuc472/project.uvprojx index 90f1e12a54..c01f7bab6e 100644 --- a/bsp/nuvoton_nuc472/project.uvprojx +++ b/bsp/nuvoton_nuc472/project.uvprojx @@ -330,7 +330,7 @@ <MiscControls /> <Define /> <Undefine /> - <IncludePath>applications;.;drivers;Libraries\CMSIS\Include;Libraries\Device\Nuvoton\NUC472_442\Include;Libraries\StdDriver\inc;..\..\include;..\..\libcpu\arm\cortex-m4;..\..\libcpu\arm\common;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh</IncludePath> + <IncludePath>applications;.;drivers;Libraries\CMSIS\Include;Libraries\Device\Nuvoton\NUC472_442\Include;Libraries\StdDriver\inc;..\..\include;..\..\libcpu\arm\cortex-m4;..\..\libcpu\arm\common;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh;..\..\components\net\lwip-2.0.2\src;..\..\components\net\lwip-2.0.2\src\include;..\..\components\net\lwip-2.0.2\src\include\ipv4;..\..\components\net\lwip-2.0.2\src\arch\include;..\..\components\net\lwip-2.0.2\src\include\netif;..\..\components\net\lwip-2.0.2\src\include\posix</IncludePath> </VariousControls> </Cads> <Aads> @@ -391,6 +391,13 @@ </Files> <Files> <File> + <FileName>nuc472_eth.c</FileName> + <FileType>1</FileType> + <FilePath>drivers\nuc472_eth.c</FilePath> + </File> + </Files> + <Files> + <File> <FileName>usart.c</FileName> <FileType>1</FileType> <FilePath>drivers\usart.c</FilePath> @@ -579,9 +586,9 @@ </Files> <Files> <File> - <FileName>sys.c</FileName> + <FileName>sys_.c</FileName> <FileType>1</FileType> - <FilePath>Libraries\StdDriver\src\sys.c</FilePath> + <FilePath>Libraries\StdDriver\src\sys_.c</FilePath> </File> </Files> <Files> @@ -856,6 +863,261 @@ </File> </Files> </Group> + <Group> + <GroupName>lwIP</GroupName> + <Files> + <File> + <FileName>sys_arch.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\arch\sys_arch.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>api_lib.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\api\api_lib.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>api_msg.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\api\api_msg.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>err.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\api\err.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>netbuf.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\api\netbuf.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>netdb.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\api\netdb.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>netifapi.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\api\netifapi.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>sockets.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\api\sockets.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>tcpip.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\api\tcpip.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>def.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\def.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>dns.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\dns.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>inet_chksum.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\inet_chksum.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>init.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\init.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>ip.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\ip.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>memp.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\memp.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>netif.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\netif.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>pbuf.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\pbuf.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>raw.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\raw.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>stats.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\stats.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>sys.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\sys.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>tcp.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\tcp.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>tcp_in.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\tcp_in.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>tcp_out.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\tcp_out.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>timeouts.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\timeouts.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>udp.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\udp.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>ethernet.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\netif\ethernet.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>ethernetif.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\netif\ethernetif.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>lowpan6.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\netif\lowpan6.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>autoip.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\ipv4\autoip.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>dhcp.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\ipv4\dhcp.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>etharp.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\ipv4\etharp.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>icmp.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\ipv4\icmp.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>igmp.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\ipv4\igmp.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>ip4.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\ipv4\ip4.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>ip4_addr.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\ipv4\ip4_addr.c</FilePath> + </File> + </Files> + <Files> + <File> + <FileName>ip4_frag.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\components\net\lwip-2.0.2\src\core\ipv4\ip4_frag.c</FilePath> + </File> + </Files> + </Group> </Groups> </Target> </Targets> diff --git a/bsp/nuvoton_nuc472/rtconfig.h b/bsp/nuvoton_nuc472/rtconfig.h index 579edf73c9..dccf59ecc8 100644 --- a/bsp/nuvoton_nuc472/rtconfig.h +++ b/bsp/nuvoton_nuc472/rtconfig.h @@ -110,7 +110,7 @@ #define DFS_FD_MAX 4 /* SECTION: lwip, a lighwight TCP/IP protocol stack */ -/* #define RT_USING_LWIP */ +#define RT_USING_LWIP /* Enable ICMP protocol*/ #define RT_LWIP_ICMP /* Enable UDP protocol*/ @@ -126,23 +126,14 @@ /* Using DHCP */ /* #define RT_LWIP_DHCP */ -/* ip address of target*/ -#define RT_LWIP_IPADDR0 192 -#define RT_LWIP_IPADDR1 168 -#define RT_LWIP_IPADDR2 1 -#define RT_LWIP_IPADDR3 30 +/* ip address of target */ +#define RT_LWIP_IPADDR "192.168.1.37" -/* gateway address of target*/ -#define RT_LWIP_GWADDR0 192 -#define RT_LWIP_GWADDR1 168 -#define RT_LWIP_GWADDR2 1 -#define RT_LWIP_GWADDR3 1 +/* gateway address of target */ +#define RT_LWIP_GWADDR "192.168.1.1" -/* mask address of target*/ -#define RT_LWIP_MSKADDR0 255 -#define RT_LWIP_MSKADDR1 255 -#define RT_LWIP_MSKADDR2 255 -#define RT_LWIP_MSKADDR3 0 +/* mask address of target */ +#define RT_LWIP_MSKADDR "255.255.255.0" /* tcp thread options */ #define RT_LWIP_TCPTHREAD_PRIORITY 12 diff --git a/bsp/nuvoton_nuc472/rtconfig.py b/bsp/nuvoton_nuc472/rtconfig.py index c827b105fa..a26d433eda 100644 --- a/bsp/nuvoton_nuc472/rtconfig.py +++ b/bsp/nuvoton_nuc472/rtconfig.py @@ -3,7 +3,7 @@ import os # toolchains options ARCH='arm' CPU='cortex-m4' -CROSS_TOOL='keil' +CROSS_TOOL='gcc' if os.getenv('RTT_CC'): CROSS_TOOL = os.getenv('RTT_CC') |
