Merged nuttx/nuttx into master
This commit is contained in:
commit
c46b3e869e
1
TODO
1
TODO
@ -937,6 +937,7 @@ o Network (net/, drivers/net)
|
|||||||
LM3S NO NO
|
LM3S NO NO
|
||||||
TM4C YES YES
|
TM4C YES YES
|
||||||
eZ80 NO NO
|
eZ80 NO NO
|
||||||
|
Kinetis YES YES (not tested)
|
||||||
LPC17xx YES YES (not tested)
|
LPC17xx YES YES (not tested)
|
||||||
LPC43xx YES YES (not tested)
|
LPC43xx YES YES (not tested)
|
||||||
DMxxx NIC NO NO
|
DMxxx NIC NO NO
|
||||||
|
@ -548,18 +548,27 @@ config KINETIS_ENETNTXBUFFERS
|
|||||||
Number of Ethernet Tx buffers to use. The size of one buffer is
|
Number of Ethernet Tx buffers to use. The size of one buffer is
|
||||||
determined by NET_BUFSIZE
|
determined by NET_BUFSIZE
|
||||||
|
|
||||||
config KINETIS_ENETPHYADDR
|
|
||||||
int "PHY address"
|
|
||||||
default 1
|
|
||||||
---help---
|
|
||||||
MII/RMII address of the PHY
|
|
||||||
|
|
||||||
config KINETIS_ENETUSEMII
|
config KINETIS_ENETUSEMII
|
||||||
bool "Use MII interface"
|
bool "Use MII interface"
|
||||||
default n
|
default n
|
||||||
---help---
|
---help---
|
||||||
The the MII PHY interface. Default: Use RMII interface
|
The the MII PHY interface. Default: Use RMII interface
|
||||||
|
|
||||||
|
config KINETIS_ENET_MDIOPULLUP
|
||||||
|
bool "MDIO pull-up"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
If there is no on-board pull-up resister on the MII/RMII MDIO line,
|
||||||
|
then this option may be selected in order to configure an internal
|
||||||
|
pull-up on MDIO.
|
||||||
|
|
||||||
|
config KINETIS_ENET_NORXER
|
||||||
|
bool "Suppress RXER"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
If selected, then the MII/RMII RXER output will be configured as a
|
||||||
|
GPIO and pulled low.
|
||||||
|
|
||||||
endmenu # Kinetis Ethernet Configuration
|
endmenu # Kinetis Ethernet Configuration
|
||||||
|
|
||||||
menu "Kinetis SDHC Configuration"
|
menu "Kinetis SDHC Configuration"
|
||||||
|
@ -83,12 +83,12 @@
|
|||||||
#define PIN_FTM0_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN4)
|
#define PIN_FTM0_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN4)
|
||||||
#define PIN_NMI (PIN_ALT7 | PIN_PORTA | PIN4)
|
#define PIN_NMI (PIN_ALT7 | PIN_PORTA | PIN4)
|
||||||
#define PIN_FTM0_CH2_1 (PIN_ALT3 | PIN_PORTA | PIN5)
|
#define PIN_FTM0_CH2_1 (PIN_ALT3 | PIN_PORTA | PIN5)
|
||||||
#if 0
|
#ifdef CONFIG_KINETIS_ENET_NORXER
|
||||||
|
# define PIN_RMII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5)
|
||||||
|
# define PIN_MII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5)
|
||||||
|
#else
|
||||||
# define PIN_RMII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5)
|
# define PIN_RMII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5)
|
||||||
# define PIN_MII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5)
|
# define PIN_MII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5)
|
||||||
#else
|
|
||||||
# define PIN_RMII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5)
|
|
||||||
# define PIN_MII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5)
|
|
||||||
#endif
|
#endif
|
||||||
#define PIN_CMP2_OUT_1 (PIN_ALT5 | PIN_PORTA | PIN5)
|
#define PIN_CMP2_OUT_1 (PIN_ALT5 | PIN_PORTA | PIN5)
|
||||||
#define PIN_I2S0_RX_BCLK_1 (PIN_ALT6 | PIN_PORTA | PIN5)
|
#define PIN_I2S0_RX_BCLK_1 (PIN_ALT6 | PIN_PORTA | PIN5)
|
||||||
@ -174,7 +174,11 @@
|
|||||||
#define PIN_TSI0_CH0 (PIN_ANALOG | PIN_PORTB | PIN0)
|
#define PIN_TSI0_CH0 (PIN_ANALOG | PIN_PORTB | PIN0)
|
||||||
#define PIN_I2C0_SCL_1 (PIN_ALT2 | PIN_PORTB | PIN0)
|
#define PIN_I2C0_SCL_1 (PIN_ALT2 | PIN_PORTB | PIN0)
|
||||||
#define PIN_FTM1_CH0_3 (PIN_ALT3 | PIN_PORTB | PIN0)
|
#define PIN_FTM1_CH0_3 (PIN_ALT3 | PIN_PORTB | PIN0)
|
||||||
#define PIN_RMII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0)
|
#ifdef CONFIG_KINETIS_ENET_MDIOPULLUP
|
||||||
|
# define PIN_RMII0_MDIO (PIN_ALT4_PULLUP | PIN_PORTB | PIN0)
|
||||||
|
#else
|
||||||
|
# define PIN_RMII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0)
|
||||||
|
#endif
|
||||||
#define PIN_MII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0)
|
#define PIN_MII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0)
|
||||||
#define PIN_FTM1_QD_PHA_3 (PIN_ALT6 | PIN_PORTB | PIN0)
|
#define PIN_FTM1_QD_PHA_3 (PIN_ALT6 | PIN_PORTB | PIN0)
|
||||||
#define PIN_ADC0_SE9 (PIN_ANALOG | PIN_PORTB | PIN1)
|
#define PIN_ADC0_SE9 (PIN_ANALOG | PIN_PORTB | PIN1)
|
||||||
|
@ -398,14 +398,22 @@
|
|||||||
#define PIN_MII0_COL (PIN_ALT4 | PIN_PORTA | PIN29)
|
#define PIN_MII0_COL (PIN_ALT4 | PIN_PORTA | PIN29)
|
||||||
#define PIN_MII0_CRS (PIN_ALT4 | PIN_PORTA | PIN27)
|
#define PIN_MII0_CRS (PIN_ALT4 | PIN_PORTA | PIN27)
|
||||||
#define PIN_MII0_MDC (PIN_ALT4 | PIN_PORTB | PIN1)
|
#define PIN_MII0_MDC (PIN_ALT4 | PIN_PORTB | PIN1)
|
||||||
#define PIN_MII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0)
|
#ifdef CONFIG_KINETIS_ENET_MDIOPULLUP
|
||||||
|
# define PIN_MII0_MDIO (PIN_ALT4_PULLUP | PIN_PORTB | PIN0)
|
||||||
|
#else
|
||||||
|
# define PIN_MII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0)
|
||||||
|
#endif
|
||||||
#define PIN_MII0_RXCLK (PIN_ALT4 | PIN_PORTA | PIN11)
|
#define PIN_MII0_RXCLK (PIN_ALT4 | PIN_PORTA | PIN11)
|
||||||
#define PIN_MII0_RXD0 (PIN_ALT4 | PIN_PORTA | PIN13)
|
#define PIN_MII0_RXD0 (PIN_ALT4 | PIN_PORTA | PIN13)
|
||||||
#define PIN_MII0_RXD1 (PIN_ALT4 | PIN_PORTA | PIN12)
|
#define PIN_MII0_RXD1 (PIN_ALT4 | PIN_PORTA | PIN12)
|
||||||
#define PIN_MII0_RXD2 (PIN_ALT4 | PIN_PORTA | PIN10)
|
#define PIN_MII0_RXD2 (PIN_ALT4 | PIN_PORTA | PIN10)
|
||||||
#define PIN_MII0_RXD3 (PIN_ALT4 | PIN_PORTA | PIN9)
|
#define PIN_MII0_RXD3 (PIN_ALT4 | PIN_PORTA | PIN9)
|
||||||
#define PIN_MII0_RXDV (PIN_ALT4 | PIN_PORTA | PIN14)
|
#define PIN_MII0_RXDV (PIN_ALT4 | PIN_PORTA | PIN14)
|
||||||
#define PIN_MII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5)
|
#ifdef CONFIG_KINETIS_ENET_NORXER
|
||||||
|
# define PIN_MII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5)
|
||||||
|
#else
|
||||||
|
# define PIN_MII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5)
|
||||||
|
#endif
|
||||||
#define PIN_MII0_TXCLK (PIN_ALT4 | PIN_PORTA | PIN25)
|
#define PIN_MII0_TXCLK (PIN_ALT4 | PIN_PORTA | PIN25)
|
||||||
#define PIN_MII0_TXD0 (PIN_ALT4 | PIN_PORTA | PIN16)
|
#define PIN_MII0_TXD0 (PIN_ALT4 | PIN_PORTA | PIN16)
|
||||||
#define PIN_MII0_TXD1 (PIN_ALT4 | PIN_PORTA | PIN17)
|
#define PIN_MII0_TXD1 (PIN_ALT4 | PIN_PORTA | PIN17)
|
||||||
@ -427,10 +435,18 @@
|
|||||||
|
|
||||||
#define PIN_RMII0_CRS_DV (PIN_ALT4 | PIN_PORTA | PIN14)
|
#define PIN_RMII0_CRS_DV (PIN_ALT4 | PIN_PORTA | PIN14)
|
||||||
#define PIN_RMII0_MDC (PIN_ALT4 | PIN_PORTB | PIN1)
|
#define PIN_RMII0_MDC (PIN_ALT4 | PIN_PORTB | PIN1)
|
||||||
#define PIN_RMII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0)
|
#ifdef CONFIG_KINETIS_ENET_MDIOPULLUP
|
||||||
|
# define PIN_RMII0_MDIO (PIN_ALT4_PULLUP | PIN_PORTB | PIN0)
|
||||||
|
#else
|
||||||
|
# define PIN_RMII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0)
|
||||||
|
#endif
|
||||||
#define PIN_RMII0_RXD0 (PIN_ALT4 | PIN_PORTA | PIN13)
|
#define PIN_RMII0_RXD0 (PIN_ALT4 | PIN_PORTA | PIN13)
|
||||||
#define PIN_RMII0_RXD1 (PIN_ALT4 | PIN_PORTA | PIN12)
|
#define PIN_RMII0_RXD1 (PIN_ALT4 | PIN_PORTA | PIN12)
|
||||||
#define PIN_RMII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5)
|
#ifdef CONFIG_KINETIS_ENET_NORXER
|
||||||
|
# define PIN_RMII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5)
|
||||||
|
#else
|
||||||
|
# define PIN_RMII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5)
|
||||||
|
#endif
|
||||||
#define PIN_RMII0_TXD0 (PIN_ALT4 | PIN_PORTA | PIN16)
|
#define PIN_RMII0_TXD0 (PIN_ALT4 | PIN_PORTA | PIN16)
|
||||||
#define PIN_RMII0_TXD1 (PIN_ALT4 | PIN_PORTA | PIN17)
|
#define PIN_RMII0_TXD1 (PIN_ALT4 | PIN_PORTA | PIN17)
|
||||||
#define PIN_RMII0_TXEN (PIN_ALT4 | PIN_PORTA | PIN15)
|
#define PIN_RMII0_TXEN (PIN_ALT4 | PIN_PORTA | PIN15)
|
||||||
|
@ -57,6 +57,10 @@
|
|||||||
#include <nuttx/net/arp.h>
|
#include <nuttx/net/arp.h>
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_NOINTS
|
||||||
|
# include <nuttx/wqueue.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NET_PKT
|
#ifdef CONFIG_NET_PKT
|
||||||
# include <nuttx/net/pkt.h>
|
# include <nuttx/net/pkt.h>
|
||||||
#endif
|
#endif
|
||||||
@ -76,6 +80,14 @@
|
|||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* If processing is not done at the interrupt level, then high priority
|
||||||
|
* work queue support is required.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_HPWORK)
|
||||||
|
# error High priority work queue support is required
|
||||||
|
#endif
|
||||||
|
|
||||||
/* CONFIG_KINETIS_ENETNETHIFS determines the number of physical interfaces
|
/* CONFIG_KINETIS_ENETNETHIFS determines the number of physical interfaces
|
||||||
* that will be supported.
|
* that will be supported.
|
||||||
*/
|
*/
|
||||||
@ -92,13 +104,16 @@
|
|||||||
# error "Need at least one RX buffer"
|
# error "Need at least one RX buffer"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NENET_NBUFFERS (CONFIG_KINETIS_ENETNTXBUFFERS+CONFIG_KINETIS_ENETNRXBUFFERS)
|
#define NENET_NBUFFERS \
|
||||||
|
(CONFIG_KINETIS_ENETNTXBUFFERS+CONFIG_KINETIS_ENETNRXBUFFERS)
|
||||||
|
|
||||||
#ifndef CONFIG_NET_MULTIBUFFER
|
#ifndef CONFIG_NET_MULTIBUFFER
|
||||||
# error "CONFIG_NET_MULTIBUFFER is required in the configuration"
|
# error "CONFIG_NET_MULTIBUFFER is required in the configuration"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */
|
/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per
|
||||||
|
* second.
|
||||||
|
*/
|
||||||
|
|
||||||
#define KINETIS_WDDELAY (1*CLK_TCK)
|
#define KINETIS_WDDELAY (1*CLK_TCK)
|
||||||
|
|
||||||
@ -193,8 +208,12 @@ struct kinetis_driver_s
|
|||||||
uint8_t txtail; /* The oldest busy TX descriptor */
|
uint8_t txtail; /* The oldest busy TX descriptor */
|
||||||
uint8_t txhead; /* The next TX descriptor to use */
|
uint8_t txhead; /* The next TX descriptor to use */
|
||||||
uint8_t rxtail; /* The next RX descriptor to use */
|
uint8_t rxtail; /* The next RX descriptor to use */
|
||||||
|
uint8_t phyaddr; /* Selected PHY address */
|
||||||
WDOG_ID txpoll; /* TX poll timer */
|
WDOG_ID txpoll; /* TX poll timer */
|
||||||
WDOG_ID txtimeout; /* TX timeout timer */
|
WDOG_ID txtimeout; /* TX timeout timer */
|
||||||
|
#ifdef CONFIG_NET_NOINTS
|
||||||
|
struct work_s work; /* For deferring work to the work queue */
|
||||||
|
#endif
|
||||||
struct enet_desc_s *txdesc; /* A pointer to the list of TX descriptor */
|
struct enet_desc_s *txdesc; /* A pointer to the list of TX descriptor */
|
||||||
struct enet_desc_s *rxdesc; /* A pointer to the list of RX descriptors */
|
struct enet_desc_s *rxdesc; /* A pointer to the list of RX descriptors */
|
||||||
|
|
||||||
@ -251,22 +270,43 @@ static int kinetis_txpoll(struct net_driver_s *dev);
|
|||||||
|
|
||||||
static void kinetis_receive(FAR struct kinetis_driver_s *priv);
|
static void kinetis_receive(FAR struct kinetis_driver_s *priv);
|
||||||
static void kinetis_txdone(FAR struct kinetis_driver_s *priv);
|
static void kinetis_txdone(FAR struct kinetis_driver_s *priv);
|
||||||
|
|
||||||
|
static inline void kinetis_interrupt_process(FAR struct kinetis_driver_s *priv);
|
||||||
|
#ifdef CONFIG_NET_NOINTS
|
||||||
|
static void kinetis_interrupt_work(FAR void *arg);
|
||||||
|
#endif
|
||||||
static int kinetis_interrupt(int irq, FAR void *context);
|
static int kinetis_interrupt(int irq, FAR void *context);
|
||||||
|
|
||||||
/* Watchdog timer expirations */
|
/* Watchdog timer expirations */
|
||||||
|
|
||||||
static void kinetis_txtimeout(int argc, uint32_t arg, ...);
|
static inline void kinetis_txtimeout_process(FAR struct kinetis_driver_s *priv);
|
||||||
static void kinetis_polltimer(int argc, uint32_t arg, ...);
|
#ifdef CONFIG_NET_NOINTS
|
||||||
|
static void kinetis_txtimeout_work(FAR void *arg);
|
||||||
|
#endif
|
||||||
|
static void kinetis_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||||
|
|
||||||
|
static inline void kinetis_poll_process(FAR struct kinetis_driver_s *priv);
|
||||||
|
#ifdef CONFIG_NET_NOINTS
|
||||||
|
static void kinetis_poll_work(FAR void *arg);
|
||||||
|
#endif
|
||||||
|
static void kinetis_polltimer_expiry(int argc, uint32_t arg, ...);
|
||||||
|
|
||||||
/* NuttX callback functions */
|
/* NuttX callback functions */
|
||||||
|
|
||||||
static int kinetis_ifup(struct net_driver_s *dev);
|
static int kinetis_ifup(struct net_driver_s *dev);
|
||||||
static int kinetis_ifdown(struct net_driver_s *dev);
|
static int kinetis_ifdown(struct net_driver_s *dev);
|
||||||
|
|
||||||
|
static inline void kinetis_txavail_process(FAR struct kinetis_driver_s *priv);
|
||||||
|
#ifdef CONFIG_NET_NOINTS
|
||||||
|
static void kinetis_txavail_work(FAR void *arg);
|
||||||
|
#endif
|
||||||
static int kinetis_txavail(struct net_driver_s *dev);
|
static int kinetis_txavail(struct net_driver_s *dev);
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IGMP
|
#ifdef CONFIG_NET_IGMP
|
||||||
static int kinetis_addmac(struct net_driver_s *dev, FAR const uint8_t *mac);
|
static int kinetis_addmac(struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||||
static int kinetis_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac);
|
static int kinetis_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NETDEV_PHY_IOCTL
|
#ifdef CONFIG_NETDEV_PHY_IOCTL
|
||||||
static int kinetis_ioctl(struct net_driver_s *dev, int cmd, long arg);
|
static int kinetis_ioctl(struct net_driver_s *dev, int cmd, long arg);
|
||||||
#endif
|
#endif
|
||||||
@ -278,7 +318,7 @@ static int kinetis_writemii(struct kinetis_driver_s *priv, uint8_t phyaddr,
|
|||||||
uint8_t regaddr, uint16_t data);
|
uint8_t regaddr, uint16_t data);
|
||||||
static int kinetis_readmii(struct kinetis_driver_s *priv, uint8_t phyaddr,
|
static int kinetis_readmii(struct kinetis_driver_s *priv, uint8_t phyaddr,
|
||||||
uint8_t regaddr, uint16_t *data);
|
uint8_t regaddr, uint16_t *data);
|
||||||
static inline void kinetis_initphy(struct kinetis_driver_s *priv);
|
static inline int kinetis_initphy(struct kinetis_driver_s *priv);
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
|
|
||||||
@ -463,8 +503,8 @@ static int kinetis_transmit(FAR struct kinetis_driver_s *priv)
|
|||||||
|
|
||||||
/* Setup the TX timeout watchdog (perhaps restarting the timer) */
|
/* Setup the TX timeout watchdog (perhaps restarting the timer) */
|
||||||
|
|
||||||
(void)wd_start(priv->txtimeout, KINETIS_TXTIMEOUT, kinetis_txtimeout, 1,
|
(void)wd_start(priv->txtimeout, KINETIS_TXTIMEOUT, kinetis_txtimeout_expiry, 1,
|
||||||
(uint32_t)priv);
|
(wdparm_t)priv);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -776,28 +816,25 @@ static void kinetis_txdone(FAR struct kinetis_driver_s *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: kinetis_interrupt
|
* Function: kinetis_interrupt_process
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Three interrupt sources will vector this this function:
|
* Interrupt processing. This may be performed either within the interrupt
|
||||||
* 1. Ethernet MAC transmit interrupt handler
|
* handler or on the worker thread, depending upon the configuration
|
||||||
* 2. Ethernet MAC receive interrupt handler
|
|
||||||
* 3.
|
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* irq - Number of the IRQ that generated the interrupt
|
* priv - Reference to the driver state structure
|
||||||
* context - Interrupt register state save info (architecture-specific)
|
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* OK on success
|
* None
|
||||||
*
|
*
|
||||||
* Assumptions:
|
* Assumptions:
|
||||||
|
* The network is locked.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int kinetis_interrupt(int irq, FAR void *context)
|
static inline void kinetis_interrupt_process(FAR struct kinetis_driver_s *priv)
|
||||||
{
|
{
|
||||||
register FAR struct kinetis_driver_s *priv = &g_enet[0];
|
|
||||||
uint32_t pending;
|
uint32_t pending;
|
||||||
|
|
||||||
/* Get the set of unmasked, pending interrupt. */
|
/* Get the set of unmasked, pending interrupt. */
|
||||||
@ -847,33 +884,130 @@ static int kinetis_interrupt(int irq, FAR void *context)
|
|||||||
|
|
||||||
putreg32(ENET_RDAR, KINETIS_ENET_RDAR);
|
putreg32(ENET_RDAR, KINETIS_ENET_RDAR);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: kinetis_interrupt_work
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Perform interrupt related work from the worker thread
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* arg - The argument passed when work_queue() was called.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK on success
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The network is locked.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_NOINTS
|
||||||
|
static void kinetis_interrupt_work(FAR void *arg)
|
||||||
|
{
|
||||||
|
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||||
|
net_lock_t state;
|
||||||
|
|
||||||
|
/* Process pending Ethernet interrupts */
|
||||||
|
|
||||||
|
state = net_lock();
|
||||||
|
kinetis_interrupt_process(priv);
|
||||||
|
net_unlock(state);
|
||||||
|
|
||||||
|
/* Re-enable Ethernet interrupts */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
up_enable_irq(KINETIS_IRQ_EMACTMR);
|
||||||
|
#endif
|
||||||
|
up_enable_irq(KINETIS_IRQ_EMACTX);
|
||||||
|
up_enable_irq(KINETIS_IRQ_EMACRX);
|
||||||
|
up_enable_irq(KINETIS_IRQ_EMACMISC);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: kinetis_interrupt
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Three interrupt sources will vector this this function:
|
||||||
|
* 1. Ethernet MAC transmit interrupt handler
|
||||||
|
* 2. Ethernet MAC receive interrupt handler
|
||||||
|
* 3.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* irq - Number of the IRQ that generated the interrupt
|
||||||
|
* context - Interrupt register state save info (architecture-specific)
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK on success
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int kinetis_interrupt(int irq, FAR void *context)
|
||||||
|
{
|
||||||
|
register FAR struct kinetis_driver_s *priv = &g_enet[0];
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_NOINTS
|
||||||
|
/* Disable further Ethernet interrupts. Because Ethernet interrupts are
|
||||||
|
* also disabled if the TX timeout event occurs, there can be no race
|
||||||
|
* condition here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
up_disable_irq(KINETIS_IRQ_EMACTMR);
|
||||||
|
up_disable_irq(KINETIS_IRQ_EMACTX);
|
||||||
|
up_disable_irq(KINETIS_IRQ_EMACRX);
|
||||||
|
up_disable_irq(KINETIS_IRQ_EMACMISC);
|
||||||
|
|
||||||
|
/* TODO: Determine if a TX transfer just completed */
|
||||||
|
|
||||||
|
{
|
||||||
|
/* If a TX transfer just completed, then cancel the TX timeout so
|
||||||
|
* there will be do race condition between any subsequent timeout
|
||||||
|
* expiration and the deferred interrupt processing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
wd_cancel(priv->txtimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cancel any pending poll work */
|
||||||
|
|
||||||
|
work_cancel(HPWORK, &priv->work);
|
||||||
|
|
||||||
|
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||||
|
|
||||||
|
work_queue(HPWORK, &priv->work, kinetis_interrupt_work, priv, 0);
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* Process the interrupt now */
|
||||||
|
|
||||||
|
kinetis_interrupt_process(priv);
|
||||||
|
#endif
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: kinetis_txtimeout
|
* Function: kinetis_txtimeout_process
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Our TX watchdog timed out. Called from the timer interrupt handler.
|
* Process a TX timeout. Called from the either the watchdog timer
|
||||||
* The last TX never completed. Reset the hardware and start again.
|
* expiration logic or from the worker thread, depending upon the
|
||||||
|
* configuration. The timeout means that the last TX never completed.
|
||||||
|
* Reset the hardware and start again.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* argc - The number of available arguments
|
* priv - Reference to the driver state structure
|
||||||
* arg - The first argument
|
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Assumptions:
|
|
||||||
* Global interrupts are disabled by the watchdog logic.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void kinetis_txtimeout(int argc, uint32_t arg, ...)
|
static inline void kinetis_txtimeout_process(FAR struct kinetis_driver_s *priv)
|
||||||
{
|
{
|
||||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
|
||||||
|
|
||||||
/* Increment statistics and dump debug info */
|
/* Increment statistics and dump debug info */
|
||||||
|
|
||||||
NETDEV_TXTIMEOUTS(&priv->dev);
|
NETDEV_TXTIMEOUTS(&priv->dev);
|
||||||
@ -891,10 +1025,42 @@ static void kinetis_txtimeout(int argc, uint32_t arg, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: kinetis_polltimer
|
* Function: kinetis_txtimeout_work
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Periodic timer handler. Called from the timer interrupt handler.
|
* Perform TX timeout related work from the worker thread
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* arg - The argument passed when work_queue() as called.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK on success
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The network is locked.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_NOINTS
|
||||||
|
static void kinetis_txtimeout_work(FAR void *arg)
|
||||||
|
{
|
||||||
|
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||||
|
net_lock_t state;
|
||||||
|
|
||||||
|
/* Process pending Ethernet interrupts */
|
||||||
|
|
||||||
|
state = net_lock();
|
||||||
|
kinetis_txtimeout_process(priv);
|
||||||
|
net_unlock(state);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: kinetis_txtimeout_expiry
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Our TX watchdog timed out. Called from the timer interrupt handler.
|
||||||
|
* The last TX never completed. Reset the hardware and start again.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* argc - The number of available arguments
|
* argc - The number of available arguments
|
||||||
@ -908,10 +1074,56 @@ static void kinetis_txtimeout(int argc, uint32_t arg, ...)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void kinetis_polltimer(int argc, uint32_t arg, ...)
|
static void kinetis_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||||
{
|
{
|
||||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_NOINTS
|
||||||
|
/* Disable further Ethernet interrupts. This will prevent some race
|
||||||
|
* conditions with interrupt work. There is still a potential race
|
||||||
|
* condition with interrupt work that is already queued and in progress.
|
||||||
|
*/
|
||||||
|
|
||||||
|
up_disable_irq(KINETIS_IRQ_EMACTMR);
|
||||||
|
up_disable_irq(KINETIS_IRQ_EMACTX);
|
||||||
|
up_disable_irq(KINETIS_IRQ_EMACRX);
|
||||||
|
up_disable_irq(KINETIS_IRQ_EMACMISC);
|
||||||
|
|
||||||
|
/* Cancel any pending poll or interrupt work. This will have no effect
|
||||||
|
* on work that has already been started.
|
||||||
|
*/
|
||||||
|
|
||||||
|
work_cancel(HPWORK, &priv->work);
|
||||||
|
|
||||||
|
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||||
|
|
||||||
|
work_queue(HPWORK, &priv->work, kinetis_txtimeout_work, priv, 0);
|
||||||
|
#else
|
||||||
|
/* Process the timeout now */
|
||||||
|
|
||||||
|
kinetis_txtimeout_process(priv);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: kinetis_poll_process
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Perform the periodic poll. This may be called either from watchdog
|
||||||
|
* timer logic or from the worker thread, depending upon the configuration.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* priv - Reference to the driver state structure
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline void kinetis_poll_process(FAR struct kinetis_driver_s *priv)
|
||||||
|
{
|
||||||
/* Check if there is there is a transmission in progress. We cannot perform
|
/* Check if there is there is a transmission in progress. We cannot perform
|
||||||
* the TX poll if he are unable to accept another packet for transmission.
|
* the TX poll if he are unable to accept another packet for transmission.
|
||||||
*/
|
*/
|
||||||
@ -928,7 +1140,89 @@ static void kinetis_polltimer(int argc, uint32_t arg, ...)
|
|||||||
|
|
||||||
/* Setup the watchdog poll timer again in any case */
|
/* Setup the watchdog poll timer again in any case */
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer, 1, arg);
|
(void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer_expiry,
|
||||||
|
1, (wdparm_t)priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: kinetis_poll_work
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Perform periodic polling from the worker thread
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* arg - The argument passed when work_queue() as called.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK on success
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The network is locked.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_NOINTS
|
||||||
|
static void kinetis_poll_work(FAR void *arg)
|
||||||
|
{
|
||||||
|
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||||
|
net_lock_t state;
|
||||||
|
|
||||||
|
/* Perform the poll */
|
||||||
|
|
||||||
|
state = net_lock();
|
||||||
|
kinetis_poll_process(priv);
|
||||||
|
net_unlock(state);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: kinetis_polltimer_expiry
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Periodic timer handler. Called from the timer interrupt handler.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* argc - The number of available arguments
|
||||||
|
* arg - The first argument
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Global interrupts are disabled by the watchdog logic.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void kinetis_polltimer_expiry(int argc, uint32_t arg, ...)
|
||||||
|
{
|
||||||
|
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_NOINTS
|
||||||
|
/* Is our single work structure available? It may not be if there are
|
||||||
|
* pending interrupt actions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (work_available(&priv->work))
|
||||||
|
{
|
||||||
|
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||||
|
|
||||||
|
work_queue(HPWORK, &priv->work, kinetis_poll_work, priv, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No.. Just re-start the watchdog poll timer, missing one polling
|
||||||
|
* cycle.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer_expiry,
|
||||||
|
1, (wdparm_t)arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* Process the interrupt now */
|
||||||
|
|
||||||
|
kinetis_poll_process(priv);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -954,6 +1248,7 @@ static int kinetis_ifup(struct net_driver_s *dev)
|
|||||||
(FAR struct kinetis_driver_s *)dev->d_private;
|
(FAR struct kinetis_driver_s *)dev->d_private;
|
||||||
uint8_t *mac = dev->d_mac.ether_addr_octet;
|
uint8_t *mac = dev->d_mac.ether_addr_octet;
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
|
int ret;
|
||||||
|
|
||||||
ninfo("Bringing up: %d.%d.%d.%d\n",
|
ninfo("Bringing up: %d.%d.%d.%d\n",
|
||||||
dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
|
dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
|
||||||
@ -986,7 +1281,12 @@ static int kinetis_ifup(struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Configure the PHY */
|
/* Configure the PHY */
|
||||||
|
|
||||||
kinetis_initphy(priv);
|
ret = kinetis_initphy(priv);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
nerr("ERROR: Failed to configure the PHY: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle promiscuous mode */
|
/* Handle promiscuous mode */
|
||||||
|
|
||||||
@ -1032,8 +1332,8 @@ static int kinetis_ifup(struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Set and activate a timer process */
|
/* Set and activate a timer process */
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer, 1,
|
(void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer_expiry, 1,
|
||||||
(uint32_t)priv);
|
(wdparm_t)priv);
|
||||||
|
|
||||||
/* Clear all pending ENET interrupt */
|
/* Clear all pending ENET interrupt */
|
||||||
|
|
||||||
@ -1108,6 +1408,77 @@ static int kinetis_ifdown(struct net_driver_s *dev)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: kinetis_txavail_process
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Perform an out-of-cycle poll.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* dev - Reference to the NuttX driver state structure
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Called in normal user mode
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline void kinetis_txavail_process(FAR struct kinetis_driver_s *priv)
|
||||||
|
{
|
||||||
|
net_lock_t state;
|
||||||
|
|
||||||
|
/* Ignore the notification if the interface is not yet up */
|
||||||
|
|
||||||
|
state = net_lock();
|
||||||
|
if (priv->bifup)
|
||||||
|
{
|
||||||
|
/* Check if there is room in the hardware to hold another outgoing
|
||||||
|
* packet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!kinetics_txringfull(priv))
|
||||||
|
{
|
||||||
|
/* No, there is space for another transfer. Poll the network for new
|
||||||
|
* XMIT data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(void)devif_poll(&priv->dev, kinetis_txpoll);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
net_unlock(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: kinetis_txavail_work
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Perform an out-of-cycle poll on the worker thread.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* arg - Reference to the NuttX driver state structure (cast to void*)
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Called on the higher priority worker thread.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_NOINTS
|
||||||
|
static void kinetis_txavail_work(FAR void *arg)
|
||||||
|
{
|
||||||
|
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||||
|
|
||||||
|
/* Perform the poll */
|
||||||
|
|
||||||
|
kinetis_txavail_process(priv);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: kinetis_txavail
|
* Function: kinetis_txavail
|
||||||
*
|
*
|
||||||
@ -1131,33 +1502,26 @@ static int kinetis_txavail(struct net_driver_s *dev)
|
|||||||
{
|
{
|
||||||
FAR struct kinetis_driver_s *priv =
|
FAR struct kinetis_driver_s *priv =
|
||||||
(FAR struct kinetis_driver_s *)dev->d_private;
|
(FAR struct kinetis_driver_s *)dev->d_private;
|
||||||
irqstate_t flags;
|
|
||||||
|
|
||||||
/* Disable interrupts because this function may be called from interrupt
|
#ifdef CONFIG_NET_NOINTS
|
||||||
* level processing.
|
/* Is our single work structure available? It may not be if there are
|
||||||
|
* pending interrupt actions and we will have to ignore the Tx
|
||||||
|
* availability action.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
flags = enter_critical_section();
|
if (work_available(&priv->work))
|
||||||
|
|
||||||
/* Ignore the notification if the interface is not yet up */
|
|
||||||
|
|
||||||
if (priv->bifup)
|
|
||||||
{
|
{
|
||||||
/* Check if there is room in the hardware to hold another outgoing
|
/* Schedule to serialize the poll on the worker thread. */
|
||||||
* packet.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!kinetics_txringfull(priv))
|
work_queue(HPWORK, &priv->work, kinetis_txavail_work, priv, 0);
|
||||||
{
|
|
||||||
/* No, there is space for another transfer. Poll the network for new
|
|
||||||
* XMIT data.
|
|
||||||
*/
|
|
||||||
|
|
||||||
(void)devif_poll(&priv->dev, kinetis_txpoll);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
#else
|
||||||
|
/* Perform the out-of-cycle poll now */
|
||||||
|
|
||||||
|
kinetis_txavail_process(priv);
|
||||||
|
#endif
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1253,7 +1617,7 @@ static int kinetis_ioctl(struct net_driver_s *dev, int cmd, long arg)
|
|||||||
{
|
{
|
||||||
struct mii_ioctl_data_s *req =
|
struct mii_ioctl_data_s *req =
|
||||||
(struct mii_ioctl_data_s *)((uintptr_t)arg);
|
(struct mii_ioctl_data_s *)((uintptr_t)arg);
|
||||||
req->phy_id = CONFIG_KINETIS_ENETPHYADDR;
|
req->phy_id = priv->phyaddr;
|
||||||
ret = OK;
|
ret = OK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1418,6 +1782,7 @@ static int kinetis_readmii(struct kinetis_driver_s *priv, uint8_t phyaddr,
|
|||||||
|
|
||||||
if (timeout >= MII_MAXPOLLS)
|
if (timeout >= MII_MAXPOLLS)
|
||||||
{
|
{
|
||||||
|
nerr("ERROR: Timed out waiting for transfer to complete\n");
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1441,31 +1806,59 @@ static int kinetis_readmii(struct kinetis_driver_s *priv, uint8_t phyaddr,
|
|||||||
* priv - Reference to the private ENET driver state structure
|
* priv - Reference to the private ENET driver state structure
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* Zero (OK) returned on success; a negated errno value is returned on any
|
||||||
|
* failure;
|
||||||
*
|
*
|
||||||
* Assumptions:
|
* Assumptions:
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static inline void kinetis_initphy(struct kinetis_driver_s *priv)
|
static inline int kinetis_initphy(struct kinetis_driver_s *priv)
|
||||||
{
|
{
|
||||||
uint32_t rcr;
|
uint32_t rcr;
|
||||||
uint32_t tcr;
|
uint32_t tcr;
|
||||||
uint16_t phydata;
|
uint16_t phydata;
|
||||||
|
uint8_t phyaddr;
|
||||||
|
int retries;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Loop (potentially infinitely?) until we successfully communicate with
|
/* Loop (potentially infinitely?) until we successfully communicate with
|
||||||
* the PHY.
|
* the PHY.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
do
|
for (phyaddr = 0; phyaddr < 32; phyaddr++)
|
||||||
{
|
{
|
||||||
usleep(LINK_WAITUS);
|
ninfo("%s: Try phyaddr: %u\n", BOARD_PHY_NAME, phyaddr);
|
||||||
phydata = 0xffff;
|
|
||||||
kinetis_readmii(priv, CONFIG_KINETIS_ENETPHYADDR, MII_PHYID1, &phydata);
|
/* Try to read PHYID1 few times using this address */
|
||||||
}
|
|
||||||
while (phydata == 0xffff);
|
retries = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
usleep(LINK_WAITUS);
|
||||||
|
ninfo("%s: Read PHYID1, retries=%d\n", BOARD_PHY_NAME, retries + 1);
|
||||||
|
phydata = 0xffff;
|
||||||
|
ret = kinetis_readmii(priv, phyaddr, MII_PHYID1, &phydata);
|
||||||
|
}
|
||||||
|
while ((ret < 0 || phydata == 0xffff) && ++retries < 3);
|
||||||
|
|
||||||
|
/* If we successfully read anything then break out, using this PHY address */
|
||||||
|
|
||||||
|
if (retries < 3)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phyaddr >= 32)
|
||||||
|
{
|
||||||
|
nerr("ERROR: Failed to read %s PHYID1 at any address\n");
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ninfo("%s: Using PHY address %u\n", BOARD_PHY_NAME, phyaddr);
|
||||||
|
priv->phyaddr = phyaddr;
|
||||||
|
|
||||||
#if CONFIG_DEBUG_NET_ERROR
|
|
||||||
/* Verify PHYID1. Compare OUI bits 3-18 */
|
/* Verify PHYID1. Compare OUI bits 3-18 */
|
||||||
|
|
||||||
ninfo("%s: PHYID1: %04x\n", BOARD_PHY_NAME, phydata);
|
ninfo("%s: PHYID1: %04x\n", BOARD_PHY_NAME, phydata);
|
||||||
@ -1473,29 +1866,35 @@ static inline void kinetis_initphy(struct kinetis_driver_s *priv)
|
|||||||
{
|
{
|
||||||
nerr("ERROR: PHYID1=%04x incorrect for %s. Expected %04x\n",
|
nerr("ERROR: PHYID1=%04x incorrect for %s. Expected %04x\n",
|
||||||
phydata, BOARD_PHY_NAME, BOARD_PHYID1);
|
phydata, BOARD_PHY_NAME, BOARD_PHYID1);
|
||||||
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/* Read PHYID2 */
|
||||||
|
|
||||||
|
ret = kinetis_readmii(priv, phyaddr, MII_PHYID2, &phydata);
|
||||||
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
/* Read PHYID2 */
|
nerr("ERROR: Failed to read %s PHYID2: %d\n", BOARD_PHY_NAME, ret);
|
||||||
|
return ret;
|
||||||
kinetis_readmii(priv, CONFIG_KINETIS_ENETPHYADDR, MII_PHYID2, &phydata);
|
}
|
||||||
ninfo("%s: PHYID2: %04x\n", BOARD_PHY_NAME, phydata);
|
|
||||||
|
ninfo("%s: PHYID2: %04x\n", BOARD_PHY_NAME, phydata);
|
||||||
/* Verify PHYID2: Compare OUI bits 19-24 and the 6-bit model number
|
|
||||||
* (ignoring the 4-bit revision number).
|
/* Verify PHYID2: Compare OUI bits 19-24 and the 6-bit model number
|
||||||
*/
|
* (ignoring the 4-bit revision number).
|
||||||
|
*/
|
||||||
if ((phydata & 0xfff0) != (BOARD_PHYID2 & 0xfff0))
|
|
||||||
{
|
if ((phydata & 0xfff0) != (BOARD_PHYID2 & 0xfff0))
|
||||||
nerr("ERROR: PHYID2=%04x incorrect for %s. Expected %04x\n",
|
{
|
||||||
(phydata & 0xfff0), BOARD_PHY_NAME, (BOARD_PHYID2 & 0xfff0));
|
nerr("ERROR: PHYID2=%04x incorrect for %s. Expected %04x\n",
|
||||||
}
|
(phydata & 0xfff0), BOARD_PHY_NAME, (BOARD_PHYID2 & 0xfff0));
|
||||||
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Start auto negotiation */
|
/* Start auto negotiation */
|
||||||
|
|
||||||
kinetis_writemii(priv, CONFIG_KINETIS_ENETPHYADDR, MII_MCR,
|
ninfo("%s: Start autonegotiation...\n", BOARD_PHY_NAME);
|
||||||
|
kinetis_writemii(priv, phyaddr, MII_MCR,
|
||||||
(MII_MCR_ANRESTART | MII_MCR_ANENABLE));
|
(MII_MCR_ANRESTART | MII_MCR_ANENABLE));
|
||||||
|
|
||||||
/* Wait (potentially forever) for auto negotiation to complete */
|
/* Wait (potentially forever) for auto negotiation to complete */
|
||||||
@ -1503,16 +1902,30 @@ static inline void kinetis_initphy(struct kinetis_driver_s *priv)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
usleep(LINK_WAITUS);
|
usleep(LINK_WAITUS);
|
||||||
kinetis_readmii(priv, CONFIG_KINETIS_ENETPHYADDR, MII_MSR, &phydata);
|
ret = kinetis_readmii(priv, phyaddr, MII_MSR, &phydata);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
nerr("ERROR: Failed to read %s MII_MSR: %d\n",
|
||||||
|
BOARD_PHY_NAME, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while ((phydata & MII_MSR_ANEGCOMPLETE) == 0);
|
while ((phydata & MII_MSR_ANEGCOMPLETE) == 0);
|
||||||
|
|
||||||
|
ninfo("%s: Autonegotiation complete\n", BOARD_PHY_NAME);
|
||||||
ninfo("%s: MII_MSR: %04x\n", BOARD_PHY_NAME, phydata);
|
ninfo("%s: MII_MSR: %04x\n", BOARD_PHY_NAME, phydata);
|
||||||
|
|
||||||
/* When we get here we have a link - Find the negotiated speed and duplex. */
|
/* When we get here we have a link - Find the negotiated speed and duplex. */
|
||||||
|
|
||||||
phydata = 0;
|
phydata = 0;
|
||||||
kinetis_readmii(priv, CONFIG_KINETIS_ENETPHYADDR, BOARD_PHY_STATUS, &phydata);
|
ret = kinetis_readmii(priv, phyaddr, BOARD_PHY_STATUS, &phydata);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
nerr("ERROR: Failed to read %s BOARD_PHY_STATUS{%02x]: %d\n",
|
||||||
|
BOARD_PHY_NAME, BOARD_PHY_STATUS, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ninfo("%s: BOARD_PHY_STATUS: %04x\n", BOARD_PHY_NAME, phydata);
|
ninfo("%s: BOARD_PHY_STATUS: %04x\n", BOARD_PHY_NAME, phydata);
|
||||||
|
|
||||||
@ -1540,29 +1953,42 @@ static inline void kinetis_initphy(struct kinetis_driver_s *priv)
|
|||||||
{
|
{
|
||||||
/* Full duplex */
|
/* Full duplex */
|
||||||
|
|
||||||
|
ninfo("%s: Full duplex\n", BOARD_PHY_NAME);
|
||||||
tcr |= ENET_TCR_FDEN;
|
tcr |= ENET_TCR_FDEN;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Half duplex */
|
/* Half duplex */
|
||||||
|
|
||||||
|
ninfo("%s: Half duplex\n", BOARD_PHY_NAME);
|
||||||
rcr |= ENET_RCR_DRT;
|
rcr |= ENET_RCR_DRT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BOARD_PHY_10BASET(phydata))
|
if (BOARD_PHY_10BASET(phydata))
|
||||||
{
|
{
|
||||||
/* 10Mbps */
|
/* 10 Mbps */
|
||||||
|
|
||||||
|
ninfo("%s: 10 Base-T\n", BOARD_PHY_NAME);
|
||||||
rcr |= ENET_RCR_RMII_10T;
|
rcr |= ENET_RCR_RMII_10T;
|
||||||
}
|
}
|
||||||
else if (!BOARD_PHY_100BASET(phydata))
|
else if (!BOARD_PHY_100BASET(phydata))
|
||||||
{
|
{
|
||||||
|
/* 100 Mbps */
|
||||||
|
|
||||||
|
ninfo("%s: 100 Base-T\n", BOARD_PHY_NAME);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This might happen if autonegotiation did not complete(?) */
|
||||||
|
|
||||||
nerr("ERROR: Neither 10- nor 100-BaseT reported: PHY STATUS=%04x\n",
|
nerr("ERROR: Neither 10- nor 100-BaseT reported: PHY STATUS=%04x\n",
|
||||||
phydata);
|
phydata);
|
||||||
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
putreg32(rcr, KINETIS_ENET_RCR);
|
putreg32(rcr, KINETIS_ENET_RCR);
|
||||||
putreg32(tcr, KINETIS_ENET_TCR);
|
putreg32(tcr, KINETIS_ENET_TCR);
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,7 @@ Contents
|
|||||||
o Freedom K64F Features
|
o Freedom K64F Features
|
||||||
o Serial Console
|
o Serial Console
|
||||||
o LEDs and Buttons
|
o LEDs and Buttons
|
||||||
o Ethernet
|
o Networking Support
|
||||||
o Development Environment
|
o Development Environment
|
||||||
o GNU Toolchain Options
|
o GNU Toolchain Options
|
||||||
o Freedom K64F Configuration Options
|
o Freedom K64F Configuration Options
|
||||||
@ -129,40 +129,286 @@ LEDs and Buttons
|
|||||||
SW2 PTC6/SPI0_SOUT/PD0_EXTRG/I2S0_RX_BCLK/FB_AD9/I2S0_MCLK/LLWU_P10
|
SW2 PTC6/SPI0_SOUT/PD0_EXTRG/I2S0_RX_BCLK/FB_AD9/I2S0_MCLK/LLWU_P10
|
||||||
SW3 PTA4/FTM0_CH1/NMI_b/LLWU_P3
|
SW3 PTA4/FTM0_CH1/NMI_b/LLWU_P3
|
||||||
|
|
||||||
Ethernet
|
Networking Support
|
||||||
========
|
==================
|
||||||
|
|
||||||
|
Ethernet MAC/KSZ8081 PHY
|
||||||
|
------------------------
|
||||||
------------ ----------------- --------------------------------------------
|
------------ ----------------- --------------------------------------------
|
||||||
KSZ8081 Board Signal(s) K64F Pin
|
KSZ8081 Board Signal(s) K64F Pin
|
||||||
Pin Signal Function
|
Pin Signal Function pinmux Name
|
||||||
--- -------- ----------------- --------------------------------------------
|
--- -------- ----------------- --------------------------------------------
|
||||||
1 VDD_1V2 VDDPLL_1.2V ---
|
1 VDD_1V2 VDDPLL_1.2V --- ---
|
||||||
2 VDDA_3V3 VDDA_ENET ---
|
2 VDDA_3V3 VDDA_ENET --- ---
|
||||||
3 RXM ENET1_RX- ---
|
3 RXM ENET1_RX- --- ---
|
||||||
4 RXP ENET1_RX+ ---
|
4 RXP ENET1_RX+ --- ---
|
||||||
5 TXM ENET1_TX- ---
|
5 TXM ENET1_TX- --- ---
|
||||||
6 TXP ENET1_TX+ ---
|
6 TXP ENET1_TX+ --- ---
|
||||||
7 X0 RMII_XTAL0 ---
|
7 X0 RMII_XTAL0 --- ---
|
||||||
8 XI RMII_XTAL1 ---
|
8 XI RMII_XTAL1 --- ---
|
||||||
9 REXT --- ---, Apparently not connected
|
9 REXT --- ---, Apparently not connected ---
|
||||||
10 MDIO RMII0_MDIO PTB0/RMII0_MDIO
|
10 MDIO RMII0_MDIO PTB0/RMII0_MDIO PIN_RMII0_MDIO
|
||||||
11 MDC RMII0_MDC PTB1/RMII0_MDC
|
11 MDC RMII0_MDC PTB1/RMII0_MDC PIN_RMII0_MDC
|
||||||
12 RXD1 RMII0_RXD_1 PTA12/RMII0_RXD1
|
12 RXD1 RMII0_RXD_1 PTA12/RMII0_RXD1 PIN_RMII0_RXD1
|
||||||
13 RXD0 RMII0_RXD_0 PTA13/RMII0_RXD0
|
13 RXD0 RMII0_RXD_0 PTA13/RMII0_RXD0 PIN_RMII0_RXD0
|
||||||
14 VDDIO VDDIO_ENET ---
|
14 VDDIO VDDIO_ENET --- ---
|
||||||
15 CRS_DIV PTA14/RMII0_CRS_DV
|
15 CRS_DIV PTA14/RMII0_CRS_DV PIN_RMII0_CRS_DV
|
||||||
16 REF_CLK RMII_RXCLK PTA18/EXTAL0, PHY clock input
|
16 REF_CLK RMII_RXCLK PTA18/EXTAL0, PHY clock input ---
|
||||||
17 RXER RMII0_RXER PTA5/RMII0_RXER
|
17 RXER RMII0_RXER PTA5/RMII0_RXER PIN_RMII0_RXER
|
||||||
18 INTRP RMII0_INT_B, J14 Pin 2, Apparently not available unless jumpered
|
18 INTRP RMII0_INT_B, J14 Pin 2, Apparently not ---
|
||||||
PHY_INT_1
|
PHY_INT_1 available unless jumpered
|
||||||
19 TXEN RMII0_TXEN PTA15/RMII0_TXEN
|
19 TXEN RMII0_TXEN PTA15/RMII0_TXEN PIN_RMII0_TXEN
|
||||||
20 TXD0 RMII0_TXD_0 PTA16/RMII0_TXD0
|
20 TXD0 RMII0_TXD_0 PTA16/RMII0_TXD0 PIN_RMII0_TXD0
|
||||||
21 TXD1 RMII0_TXD_1 PTA17/RMII0_TXD1
|
21 TXD1 RMII0_TXD_1 PTA17/RMII0_TXD1 PIN_RMII0_TXD1
|
||||||
22 GND1 --- ---
|
22 GND1 --- --- ---
|
||||||
24 nRST PHY_RST_B ---
|
24 nRST PHY_RST_B --- ---
|
||||||
25 GND2 --- ---
|
25 GND2 --- --- ---
|
||||||
--- -------- ----------------- --------------------------------------------
|
--- -------- ----------------- --------------------------------------------
|
||||||
|
|
||||||
|
No external pullup is available on MDIO signal when MK64FN1M0VLL12 MCU is
|
||||||
|
requests status of the Ethernet link connection. Internal pullup is required
|
||||||
|
when port configuration for MDIO signal is enabled:
|
||||||
|
|
||||||
|
CONFIG_KINETIS_ENET_MDIOPULLUP=y
|
||||||
|
|
||||||
|
Networking support via the can be added to NSH by selecting the following
|
||||||
|
configuration options.
|
||||||
|
|
||||||
|
Selecting the EMAC peripheral
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
System Type -> Kinetis Peripheral Support
|
||||||
|
CONFIG_KINETIS_ENET=y : Enable the EThernet MAC peripheral
|
||||||
|
|
||||||
|
System Type -> Ethernet Configuration
|
||||||
|
CONFIG_KINETIS_ENETNETHIFS=1
|
||||||
|
CONFIG_KINETIS_ENETNRXBUFFERS=6
|
||||||
|
CONFIG_KINETIS_ENETNTXBUFFERS=2
|
||||||
|
CONFIG_KINETIS_ENET_MDIOPULLUP=y
|
||||||
|
|
||||||
|
Networking Support
|
||||||
|
CONFIG_NET=y : Enable Neworking
|
||||||
|
CONFIG_NET_ETHERNET=y : Support Ethernet data link
|
||||||
|
CONFIG_NET_NOINTS=y : Should operative at non-interrupt level
|
||||||
|
CONFIG_NET_SOCKOPTS=y : Enable socket operations
|
||||||
|
CONFIG_NET_MULTIBUFFER=y : Multi-packet buffer option required
|
||||||
|
CONFIG_NET_ETH_MTU=590 : Maximum packet size (MTU) 1518 is more standard
|
||||||
|
CONFIG_NET_ETH_TCP_RECVWNDO=536 : Should be the same as CONFIG_NET_ETH_MTU
|
||||||
|
CONFIG_NET_ARP=y : Enable ARP
|
||||||
|
CONFIG_NET_ARPTAB_SIZE=16 : ARP table size
|
||||||
|
CONFIG_NET_ARP_IPIN=y : Enable ARP address harvesting
|
||||||
|
CONFIG_NET_ARP_SEND=y : Send ARP request before sending data
|
||||||
|
CONFIG_NET_TCP=y : Enable TCP/IP networking
|
||||||
|
CONFIG_NET_TCP_READAHEAD=y : Support TCP read-ahead
|
||||||
|
CONFIG_NET_TCP_WRITE_BUFFERS=y : Support TCP write-buffering
|
||||||
|
CONFIG_NET_TCPBACKLOG=y : Support TCP/IP backlog
|
||||||
|
CONFIG_NET_MAX_LISTENPORTS=20 :
|
||||||
|
CONFIG_NET_TCP_READAHEAD_BUFSIZE=536 Read-ahead buffer size
|
||||||
|
CONFIG_NET_UDP=y : Enable UDP networking
|
||||||
|
CONFIG_NET_BROADCAST=y : Needed for DNS name resolution
|
||||||
|
CONFIG_NET_ICMP=y : Enable ICMP networking
|
||||||
|
CONFIG_NET_ICMP_PING=y : Needed for NSH ping command
|
||||||
|
: Defaults should be okay for other options
|
||||||
|
f Application Configuration -> Network Utilities
|
||||||
|
CONFIG_NETDB_DNSCLIENT=y : Enable host address resolution
|
||||||
|
CONFIG_NETUTILS_TELNETD=y : Enable the Telnet daemon
|
||||||
|
CONFIG_NETUTILS_TFTPC=y : Enable TFTP data file transfers for get and put commands
|
||||||
|
CONFIG_NETUTILS_NETLIB=y : Network library support is needed
|
||||||
|
CONFIG_NETUTILS_WEBCLIENT=y : Needed for wget support
|
||||||
|
: Defaults should be okay for other options
|
||||||
|
Application Configuration -> NSH Library
|
||||||
|
CONFIG_NSH_TELNET=y : Enable NSH session via Telnet
|
||||||
|
CONFIG_NSH_IPADDR=0x0a000002 : Select a fixed IP address
|
||||||
|
CONFIG_NSH_DRIPADDR=0x0a000001 : IP address of gateway/host PC
|
||||||
|
CONFIG_NSH_NETMASK=0xffffff00 : Netmask
|
||||||
|
CONFIG_NSH_NOMAC=y : Need to make up a bogus MAC address
|
||||||
|
: Defaults should be okay for other options
|
||||||
|
|
||||||
|
You can also enable enable the DHCPC client for networks that use
|
||||||
|
dynamically assigned address:
|
||||||
|
|
||||||
|
Application Configuration -> Network Utilities
|
||||||
|
CONFIG_NETUTILS_DHCPC=y : Enables the DHCP client
|
||||||
|
|
||||||
|
Networking Support
|
||||||
|
CONFIG_NET_UDP=y : Depends on broadcast UDP
|
||||||
|
|
||||||
|
Application Configuration -> NSH Library
|
||||||
|
CONFIG_NET_BROADCAST=y
|
||||||
|
CONFIG_NSH_DHCPC=y : Tells NSH to use DHCPC, not
|
||||||
|
: the fixed addresses
|
||||||
|
|
||||||
|
Using the network with NSH
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
So what can you do with this networking support? First you see that
|
||||||
|
NSH has several new network related commands:
|
||||||
|
|
||||||
|
ifconfig, ifdown, ifup: Commands to help manage your network
|
||||||
|
get and put: TFTP file transfers
|
||||||
|
wget: HTML file transfers
|
||||||
|
ping: Check for access to peers on the network
|
||||||
|
Telnet console: You can access the NSH remotely via telnet.
|
||||||
|
|
||||||
|
You can also enable other add on features like full FTP or a Web
|
||||||
|
Server or XML RPC and others. There are also other features that
|
||||||
|
you can enable like DHCP client (or server) or network name
|
||||||
|
resolution.
|
||||||
|
|
||||||
|
By default, the IP address of the DK-TM4C129X will be 10.0.0.2 and
|
||||||
|
it will assume that your host is the gateway and has the IP address
|
||||||
|
10.0.0.1.
|
||||||
|
|
||||||
|
nsh> ifconfig
|
||||||
|
eth0 HWaddr 00:e0:de:ad:be:ef at UP
|
||||||
|
IPaddr:10.0.0.2 DRaddr:10.0.0.1 Mask:255.255.255.0
|
||||||
|
|
||||||
|
You can use ping to test for connectivity to the host (Careful,
|
||||||
|
Window firewalls usually block ping-related ICMP traffic). On the
|
||||||
|
target side, you can:
|
||||||
|
|
||||||
|
nsh> ping 10.0.0.1
|
||||||
|
PING 10.0.0.1 56 bytes of data
|
||||||
|
56 bytes from 10.0.0.1: icmp_seq=1 time=0 ms
|
||||||
|
56 bytes from 10.0.0.1: icmp_seq=2 time=0 ms
|
||||||
|
56 bytes from 10.0.0.1: icmp_seq=3 time=0 ms
|
||||||
|
56 bytes from 10.0.0.1: icmp_seq=4 time=0 ms
|
||||||
|
56 bytes from 10.0.0.1: icmp_seq=5 time=0 ms
|
||||||
|
56 bytes from 10.0.0.1: icmp_seq=6 time=0 ms
|
||||||
|
56 bytes from 10.0.0.1: icmp_seq=7 time=0 ms
|
||||||
|
56 bytes from 10.0.0.1: icmp_seq=8 time=0 ms
|
||||||
|
56 bytes from 10.0.0.1: icmp_seq=9 time=0 ms
|
||||||
|
56 bytes from 10.0.0.1: icmp_seq=10 time=0 ms
|
||||||
|
10 packets transmitted, 10 received, 0% packet loss, time 10100 ms
|
||||||
|
|
||||||
|
NOTE: In this configuration is is normal to have packet loss > 0%
|
||||||
|
the first time you ping due to the default handling of the ARP
|
||||||
|
table.
|
||||||
|
|
||||||
|
On the host side, you should also be able to ping the DK-TM4C129X:
|
||||||
|
|
||||||
|
$ ping 10.0.0.2
|
||||||
|
|
||||||
|
You can also log into the NSH from the host PC like this:
|
||||||
|
|
||||||
|
$ telnet 10.0.0.2
|
||||||
|
Trying 10.0.0.2...
|
||||||
|
Connected to 10.0.0.2.
|
||||||
|
Escape character is '^]'.
|
||||||
|
sh_telnetmain: Session [3] Started
|
||||||
|
|
||||||
|
NuttShell (NSH) NuttX-6.31
|
||||||
|
nsh> help
|
||||||
|
help usage: help [-v] [<cmd>]
|
||||||
|
|
||||||
|
[ echo ifconfig mkdir mw sleep
|
||||||
|
? exec ifdown mkfatfs ping test
|
||||||
|
cat exit ifup mkfifo ps umount
|
||||||
|
cp free kill mkrd put usleep
|
||||||
|
cmp get losetup mh rm wget
|
||||||
|
dd help ls mount rmdir xd
|
||||||
|
df hexdump mb mv sh
|
||||||
|
|
||||||
|
Builtin Apps:
|
||||||
|
nsh>
|
||||||
|
|
||||||
|
NOTE: If you enable this networking as described above, you will
|
||||||
|
experience a delay on booting NSH. That is because the start-up logic
|
||||||
|
waits for the network connection to be established before starting
|
||||||
|
NuttX. In a real application, you would probably want to do the
|
||||||
|
network bringup on a separate thread so that access to the NSH prompt
|
||||||
|
is not delayed.
|
||||||
|
|
||||||
|
This delay will be especially long if the board is not connected to
|
||||||
|
a network. On the order of minutes! You will probably think that
|
||||||
|
NuttX has crashed! And then, when it finally does come up after
|
||||||
|
numerous timeouts and retries, the network will not be available --
|
||||||
|
even if the network cable is plugged in later.
|
||||||
|
|
||||||
|
The long delays can be eliminated by using a separate the network
|
||||||
|
initialization thread discussed below. Recovering after the network
|
||||||
|
becomes available requires the network monitor feature, also discussed
|
||||||
|
below.
|
||||||
|
|
||||||
|
Network Initialization Thread
|
||||||
|
-----------------------------
|
||||||
|
There is a configuration option enabled by CONFIG_NSH_NETINIT_THREAD
|
||||||
|
that will do the NSH network bring-up asynchronously in parallel on
|
||||||
|
a separate thread. This eliminates the (visible) networking delay
|
||||||
|
altogether. This current implementation, however, has some limitations:
|
||||||
|
|
||||||
|
- If no network is connected, the network bring-up will fail and
|
||||||
|
the network initialization thread will simply exit. There are no
|
||||||
|
retries and no mechanism to know if the network initialization was
|
||||||
|
successful (it could perform a network Ioctl to see if the link is
|
||||||
|
up and it now, keep trying, but it does not do that now).
|
||||||
|
|
||||||
|
- Furthermore, there is currently no support for detecting loss of
|
||||||
|
network connection and recovery of the connection (similarly, this
|
||||||
|
thread could poll periodically for network status, but does not).
|
||||||
|
|
||||||
|
Both of these shortcomings could be eliminated by enabling the network
|
||||||
|
monitor:
|
||||||
|
|
||||||
|
Network Monitor
|
||||||
|
---------------
|
||||||
|
By default the network initialization thread will bring-up the network
|
||||||
|
then exit, freeing all of the resources that it required. This is a
|
||||||
|
good behavior for systems with limited memory.
|
||||||
|
|
||||||
|
If the CONFIG_NSH_NETINIT_MONITOR option is selected, however, then the
|
||||||
|
network initialization thread will persist forever; it will monitor the
|
||||||
|
network status. In the event that the network goes down (for example, if
|
||||||
|
a cable is removed), then the thread will monitor the link status and
|
||||||
|
attempt to bring the network back up. In this case the resources
|
||||||
|
required for network initialization are never released.
|
||||||
|
|
||||||
|
Pre-requisites:
|
||||||
|
|
||||||
|
- CONFIG_NSH_NETINIT_THREAD as described above.
|
||||||
|
|
||||||
|
- The K64F EMAC block does not support PHY interrupts. The KSZ8081
|
||||||
|
PHY interrupt line is brought to a jumper block and it should be
|
||||||
|
possible to connect that some some interrupt port pin. You would
|
||||||
|
need to provide some custom logic in the Freedcom K64F
|
||||||
|
configuration to set up that PHY interrupt.
|
||||||
|
|
||||||
|
- In addtion to the PHY interrupt, the Network Monitor also requires the
|
||||||
|
following setting:
|
||||||
|
|
||||||
|
CONFIG_NETDEV_PHY_IOCTL. Enable PHY IOCTL commands in the Ethernet
|
||||||
|
device driver. Special IOCTL commands must be provided by the Ethernet
|
||||||
|
driver to support certain PHY operations that will be needed for link
|
||||||
|
management. There operations are not complex and are implemented for
|
||||||
|
the Atmel SAMA5 family.
|
||||||
|
|
||||||
|
CONFIG_ARCH_PHY_INTERRUPT. This is not a user selectable option.
|
||||||
|
Rather, it is set when you select a board that supports PHY
|
||||||
|
interrupts. For the K64F, like most other architectures, the PHY
|
||||||
|
interrupt must be provided via some board-specific GPIO. In any
|
||||||
|
event, the board-specific logic must provide support for the PHY
|
||||||
|
interrupt. To do this, the board logic must do two things: (1) It
|
||||||
|
must provide the function arch_phy_irq() as described and prototyped
|
||||||
|
in the nuttx/include/nuttx/arch.h, and (2) it must select
|
||||||
|
CONFIG_ARCH_PHY_INTERRUPT in the board configuration file to
|
||||||
|
advertise that it supports arch_phy_irq().
|
||||||
|
|
||||||
|
And a few other things: UDP support is required (CONFIG_NET_UDP) and
|
||||||
|
signals must not be disabled (CONFIG_DISABLE_SIGNALS).
|
||||||
|
|
||||||
|
Given those prerequisites, the network monitor can be selected with these
|
||||||
|
additional settings.
|
||||||
|
|
||||||
|
System Type -> Kinetis Ethernet Configuration
|
||||||
|
CONFIG_ARCH_PHY_INTERRUPT=y : (auto-selected)
|
||||||
|
CONFIG_NETDEV_PHY_IOCTL=y : (auto-selected)
|
||||||
|
|
||||||
|
Application Configuration -> NSH Library -> Networking Configuration
|
||||||
|
CONFIG_NSH_NETINIT_THREAD : Enable the network initialization thread
|
||||||
|
CONFIG_NSH_NETINIT_MONITOR=y : Enable the network monitor
|
||||||
|
CONFIG_NSH_NETINIT_RETRYMSEC=2000 : Configure the network monitor as you like
|
||||||
|
CONFIG_NSH_NETINIT_SIGNO=18
|
||||||
|
|
||||||
Development Environment
|
Development Environment
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
@ -400,6 +646,24 @@ Where <subdir> is one of the following:
|
|||||||
CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIW=y : ARM/mbed toolcahin (arm-none-elf-gcc)
|
CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIW=y : ARM/mbed toolcahin (arm-none-elf-gcc)
|
||||||
CONFIG_INTELHEX_BINARY=y : Output formats: Intel hex binary
|
CONFIG_INTELHEX_BINARY=y : Output formats: Intel hex binary
|
||||||
|
|
||||||
|
3. No external pullup is available on MDIO signal when MK64FN1M0VLL12 MCU
|
||||||
|
is requests status of the Ethernet link connection. Internal pullup is
|
||||||
|
required when port configuration for MDIO signal is enabled:
|
||||||
|
|
||||||
|
CONFIG_KINETIS_ENET_MDIOPULLUP=y
|
||||||
|
|
||||||
|
4. Configured to use a fixed IPv4 address:
|
||||||
|
|
||||||
|
CONFIG_NSH_IPADDR=0x0a000002
|
||||||
|
CONFIG_NSH_DRIPADDR=0x0a000001
|
||||||
|
CONFIG_NSH_NETMASK=0xffffff00
|
||||||
|
|
||||||
|
And a bogus MAC address:
|
||||||
|
|
||||||
|
CONFIG_NSH_NOMAC=y
|
||||||
|
CONFIG_NSH_SWMAC=y
|
||||||
|
CONFIG_NSH_MACADDR=0x00e0deadbeef
|
||||||
|
|
||||||
nsh:
|
nsh:
|
||||||
---
|
---
|
||||||
Configures the NuttShell (nsh) located at apps/examples/nsh using a
|
Configures the NuttShell (nsh) located at apps/examples/nsh using a
|
||||||
@ -455,5 +719,13 @@ Status
|
|||||||
NSH configuration is working and LEDs are working. The only odd
|
NSH configuration is working and LEDs are working. The only odd
|
||||||
behavior that I see is that pressing SW3 causes an unexpected interrupt
|
behavior that I see is that pressing SW3 causes an unexpected interrupt
|
||||||
error.
|
error.
|
||||||
|
|
||||||
2016-07-12: Added support for the KSZ8081 PHY and added the netnsh
|
2016-07-12: Added support for the KSZ8081 PHY and added the netnsh
|
||||||
configuration. Untested as of this writing.
|
configuration. The network is basically functional, but a lot more
|
||||||
|
testing is needed to confirm that.
|
||||||
|
|
||||||
|
In testing, I notice a strange thing. If I run at full optimization the
|
||||||
|
code runs (albeit with bugs-to-be-solved). But with no optimization or
|
||||||
|
even at -O1, the system fails to boot. This seems to be related to the
|
||||||
|
watchdog timer.
|
||||||
|
|
||||||
|
@ -41,8 +41,9 @@
|
|||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
@ -68,7 +69,7 @@
|
|||||||
*
|
*
|
||||||
* PLL Input frequency: PLLIN = REFCLK / PRDIV = 50 Mhz / 20 = 2.5 MHz
|
* PLL Input frequency: PLLIN = REFCLK / PRDIV = 50 Mhz / 20 = 2.5 MHz
|
||||||
* PLL Output frequency: PLLOUT = PLLIN * VDIV = 2.5 Mhz * 48 = 120 MHz
|
* PLL Output frequency: PLLOUT = PLLIN * VDIV = 2.5 Mhz * 48 = 120 MHz
|
||||||
* MCG Frequency: PLLOUT = 96MHz
|
* MCG Frequency: PLLOUT = 120 MHz
|
||||||
*
|
*
|
||||||
* PRDIV register value is the divider minus one. So 20 -> 19
|
* PRDIV register value is the divider minus one. So 20 -> 19
|
||||||
* VDIV regiser value is offset by 24. So 28 -> 24
|
* VDIV regiser value is offset by 24. So 28 -> 24
|
||||||
@ -100,36 +101,37 @@
|
|||||||
* SDCLK frequency = (base clock) / (prescaler * divisor)
|
* SDCLK frequency = (base clock) / (prescaler * divisor)
|
||||||
*
|
*
|
||||||
* The SDHC module is always configure configured so that the core clock is the base
|
* The SDHC module is always configure configured so that the core clock is the base
|
||||||
* clock.
|
* clock. Possible values for presscaler and divisor are:
|
||||||
|
*
|
||||||
|
* SDCLKFS: {2, 4, 8, 16, 32, 63, 128, 256}
|
||||||
|
* DVS: {1..16}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Identification mode: 400KHz = 96MHz / ( 16 * 15) */
|
/* Identification mode: Optimal 400KHz, Actual 120MHz / (32 * 10) = 375 Khz */
|
||||||
|
|
||||||
#define BOARD_SDHC_IDMODE_PRESCALER SDHC_SYSCTL_SDCLKFS_DIV16
|
#define BOARD_SDHC_IDMODE_PRESCALER SDHC_SYSCTL_SDCLKFS_DIV32
|
||||||
#define BOARD_SDHC_IDMODE_DIVISOR SDHC_SYSCTL_DVS_DIV(15)
|
#define BOARD_SDHC_IDMODE_DIVISOR SDHC_SYSCTL_DVS_DIV(10)
|
||||||
|
|
||||||
/* MMC normal mode: 16MHz = 96MHz / (2 * 3) */
|
/* MMC normal mode: Optimal 20MHz, Actual 120MHz / (2 * 3) = 20 MHz */
|
||||||
|
|
||||||
#define BOARD_SDHC_MMCMODE_PRESCALER SDHC_SYSCTL_SDCLKFS_DIV2
|
#define BOARD_SDHC_MMCMODE_PRESCALER SDHC_SYSCTL_SDCLKFS_DIV2
|
||||||
#define BOARD_SDHC_MMCMODE_DIVISOR SDHC_SYSCTL_DVS_DIV(3)
|
#define BOARD_SDHC_MMCMODE_DIVISOR SDHC_SYSCTL_DVS_DIV(3)
|
||||||
|
|
||||||
/* SD normal mode (1-bit): 16MHz = 96MHz / (2 * 3) */
|
/* SD normal mode (1-bit): Optimal 20MHz, Actual 120MHz / (2 * 3) = 20 MHz */
|
||||||
|
|
||||||
#define BOARD_SDHC_SD1MODE_PRESCALER SDHC_SYSCTL_SDCLKFS_DIV2
|
#define BOARD_SDHC_SD1MODE_PRESCALER SDHC_SYSCTL_SDCLKFS_DIV2
|
||||||
#define BOARD_SDHC_SD1MODE_DIVISOR SDHC_SYSCTL_DVS_DIV(3)
|
#define BOARD_SDHC_SD1MODE_DIVISOR SDHC_SYSCTL_DVS_DIV(3)
|
||||||
|
|
||||||
/* SD normal mode (4-bit): 24MHz = 96MHz / (2 * 2) (with DMA)
|
/* SD normal mode (4-bit): Optimal 25MHz, Actual 120MHz / (2 * 3) = 20 MHz (with DMA)
|
||||||
* SD normal mode (4-bit): 16MHz = 96MHz / (2 * 3) (no DMA)
|
* SD normal mode (4-bit): Optimal 20MHz, Actual 120MHz / (2 * 3) = 20 MHz (no DMA)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_SDIO_DMA
|
#ifdef CONFIG_SDIO_DMA
|
||||||
# define BOARD_SDHC_SD4MODE_PRESCALER SDHC_SYSCTL_SDCLKFS_DIV2
|
# define BOARD_SDHC_SD4MODE_PRESCALER SDHC_SYSCTL_SDCLKFS_DIV2
|
||||||
# define BOARD_SDHC_SD4MODE_DIVISOR SDHC_SYSCTL_DVS_DIV(2)
|
# define BOARD_SDHC_SD4MODE_DIVISOR SDHC_SYSCTL_DVS_DIV(3)
|
||||||
#else
|
#else
|
||||||
//# define BOARD_SDHC_SD4MODE_PRESCALER SDHC_SYSCTL_SDCLKFS_DIV2
|
# define BOARD_SDHC_SD4MODE_PRESCALER SDHC_SYSCTL_SDCLKFS_DIV2
|
||||||
//# define BOARD_SDHC_SD4MODE_DIVISOR SDHC_SYSCTL_DVS_DIV(3)
|
# define BOARD_SDHC_SD4MODE_DIVISOR SDHC_SYSCTL_DVS_DIV(3)
|
||||||
# define BOARD_SDHC_SD4MODE_PRESCALER SDHC_SYSCTL_SDCLKFS_DIV16
|
|
||||||
# define BOARD_SDHC_SD4MODE_DIVISOR SDHC_SYSCTL_DVS_DIV(15)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* LED definitions ******************************************************************/
|
/* LED definitions ******************************************************************/
|
||||||
|
@ -245,8 +245,9 @@ CONFIG_KINETIS_ENET=y
|
|||||||
CONFIG_KINETIS_ENETNETHIFS=1
|
CONFIG_KINETIS_ENETNETHIFS=1
|
||||||
CONFIG_KINETIS_ENETNRXBUFFERS=6
|
CONFIG_KINETIS_ENETNRXBUFFERS=6
|
||||||
CONFIG_KINETIS_ENETNTXBUFFERS=2
|
CONFIG_KINETIS_ENETNTXBUFFERS=2
|
||||||
CONFIG_KINETIS_ENETPHYADDR=1
|
|
||||||
# CONFIG_KINETIS_ENETUSEMII is not set
|
# CONFIG_KINETIS_ENETUSEMII is not set
|
||||||
|
CONFIG_KINETIS_ENET_MDIOPULLUP=y
|
||||||
|
# CONFIG_KINETIS_ENET_NORXER is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Kinetis UART Configuration
|
# Kinetis UART Configuration
|
||||||
@ -331,7 +332,14 @@ CONFIG_ARCH_HAVE_IRQBUTTONS=y
|
|||||||
# Board-Specific Options
|
# Board-Specific Options
|
||||||
#
|
#
|
||||||
# CONFIG_BOARD_CRASHDUMP is not set
|
# CONFIG_BOARD_CRASHDUMP is not set
|
||||||
# CONFIG_LIB_BOARDCTL is not set
|
CONFIG_LIB_BOARDCTL=y
|
||||||
|
# CONFIG_BOARDCTL_RESET is not set
|
||||||
|
# CONFIG_BOARDCTL_UNIQUEID is not set
|
||||||
|
# CONFIG_BOARDCTL_TSCTEST is not set
|
||||||
|
# CONFIG_BOARDCTL_ADCTEST is not set
|
||||||
|
# CONFIG_BOARDCTL_PWMTEST is not set
|
||||||
|
# CONFIG_BOARDCTL_GRAPHICS is not set
|
||||||
|
# CONFIG_BOARDCTL_IOCTL is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# RTOS Features
|
# RTOS Features
|
||||||
@ -403,6 +411,7 @@ CONFIG_NAME_MAX=32
|
|||||||
# CONFIG_SCHED_STARTHOOK is not set
|
# CONFIG_SCHED_STARTHOOK is not set
|
||||||
# CONFIG_SCHED_ATEXIT is not set
|
# CONFIG_SCHED_ATEXIT is not set
|
||||||
# CONFIG_SCHED_ONEXIT is not set
|
# CONFIG_SCHED_ONEXIT is not set
|
||||||
|
# CONFIG_SIG_EVTHREAD is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Signal Numbers
|
# Signal Numbers
|
||||||
@ -411,6 +420,7 @@ CONFIG_SIG_SIGUSR1=1
|
|||||||
CONFIG_SIG_SIGUSR2=2
|
CONFIG_SIG_SIGUSR2=2
|
||||||
CONFIG_SIG_SIGALARM=3
|
CONFIG_SIG_SIGALARM=3
|
||||||
CONFIG_SIG_SIGCONDTIMEDOUT=16
|
CONFIG_SIG_SIGCONDTIMEDOUT=16
|
||||||
|
CONFIG_SIG_SIGWORK=17
|
||||||
|
|
||||||
#
|
#
|
||||||
# POSIX Message Queue Options
|
# POSIX Message Queue Options
|
||||||
@ -422,8 +432,11 @@ CONFIG_MQ_MAXMSGSIZE=32
|
|||||||
#
|
#
|
||||||
# Work queue support
|
# Work queue support
|
||||||
#
|
#
|
||||||
# CONFIG_SCHED_WORKQUEUE is not set
|
CONFIG_SCHED_WORKQUEUE=y
|
||||||
# CONFIG_SCHED_HPWORK is not set
|
CONFIG_SCHED_HPWORK=y
|
||||||
|
CONFIG_SCHED_HPWORKPRIORITY=224
|
||||||
|
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||||
|
CONFIG_SCHED_HPWORKSTACKSIZE=2048
|
||||||
# CONFIG_SCHED_LPWORK is not set
|
# CONFIG_SCHED_LPWORK is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -615,7 +628,7 @@ CONFIG_SYSLOG_CONSOLE=y
|
|||||||
CONFIG_ARCH_HAVE_NET=y
|
CONFIG_ARCH_HAVE_NET=y
|
||||||
CONFIG_ARCH_HAVE_PHY=y
|
CONFIG_ARCH_HAVE_PHY=y
|
||||||
CONFIG_NET=y
|
CONFIG_NET=y
|
||||||
# CONFIG_NET_NOINTS is not set
|
CONFIG_NET_NOINTS=y
|
||||||
# CONFIG_NET_PROMISCUOUS is not set
|
# CONFIG_NET_PROMISCUOUS is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -759,7 +772,16 @@ CONFIG_FS_FAT=y
|
|||||||
# CONFIG_FS_ROMFS is not set
|
# CONFIG_FS_ROMFS is not set
|
||||||
# CONFIG_FS_TMPFS is not set
|
# CONFIG_FS_TMPFS is not set
|
||||||
# CONFIG_FS_SMARTFS is not set
|
# CONFIG_FS_SMARTFS is not set
|
||||||
# CONFIG_FS_PROCFS is not set
|
CONFIG_FS_PROCFS=y
|
||||||
|
CONFIG_FS_PROCFS_REGISTER=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# Exclude individual procfs entries
|
||||||
|
#
|
||||||
|
# CONFIG_FS_PROCFS_EXCLUDE_PROCESS is not set
|
||||||
|
# CONFIG_FS_PROCFS_EXCLUDE_UPTIME is not set
|
||||||
|
# CONFIG_FS_PROCFS_EXCLUDE_MOUNTS is not set
|
||||||
|
# CONFIG_FS_PROCFS_EXCLUDE_NET is not set
|
||||||
# CONFIG_FS_UNIONFS is not set
|
# CONFIG_FS_UNIONFS is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -918,6 +940,7 @@ CONFIG_EXAMPLES_NSH=y
|
|||||||
# CONFIG_EXAMPLES_TOUCHSCREEN is not set
|
# CONFIG_EXAMPLES_TOUCHSCREEN is not set
|
||||||
# CONFIG_EXAMPLES_UDP is not set
|
# CONFIG_EXAMPLES_UDP is not set
|
||||||
# CONFIG_EXAMPLES_UDPBLASTER is not set
|
# CONFIG_EXAMPLES_UDPBLASTER is not set
|
||||||
|
# CONFIG_EXAMPLES_USBSERIAL is not set
|
||||||
# CONFIG_EXAMPLES_USBTERM is not set
|
# CONFIG_EXAMPLES_USBTERM is not set
|
||||||
# CONFIG_EXAMPLES_WATCHDOG is not set
|
# CONFIG_EXAMPLES_WATCHDOG is not set
|
||||||
# CONFIG_EXAMPLES_WEBSERVER is not set
|
# CONFIG_EXAMPLES_WEBSERVER is not set
|
||||||
@ -1057,6 +1080,7 @@ CONFIG_NSH_MMCSDMINOR=0
|
|||||||
CONFIG_NSH_CMDOPT_DF_H=y
|
CONFIG_NSH_CMDOPT_DF_H=y
|
||||||
CONFIG_NSH_CODECS_BUFSIZE=128
|
CONFIG_NSH_CODECS_BUFSIZE=128
|
||||||
CONFIG_NSH_CMDOPT_HEXDUMP=y
|
CONFIG_NSH_CMDOPT_HEXDUMP=y
|
||||||
|
CONFIG_NSH_PROC_MOUNTPOINT="/proc"
|
||||||
CONFIG_NSH_FILEIOSIZE=512
|
CONFIG_NSH_FILEIOSIZE=512
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -1070,7 +1094,7 @@ CONFIG_NSH_FILEIOSIZE=512
|
|||||||
# Console Configuration
|
# Console Configuration
|
||||||
#
|
#
|
||||||
CONFIG_NSH_CONSOLE=y
|
CONFIG_NSH_CONSOLE=y
|
||||||
# CONFIG_NSH_ARCHINIT is not set
|
CONFIG_NSH_ARCHINIT=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# Networking Configuration
|
# Networking Configuration
|
||||||
|
@ -192,6 +192,8 @@ CONFIG_ARCH_FAMILY_K64=y
|
|||||||
CONFIG_KINETIS_UART3=y
|
CONFIG_KINETIS_UART3=y
|
||||||
# CONFIG_KINETIS_UART4 is not set
|
# CONFIG_KINETIS_UART4 is not set
|
||||||
# CONFIG_KINETIS_UART5 is not set
|
# CONFIG_KINETIS_UART5 is not set
|
||||||
|
# CONFIG_KINETIS_ENET is not set
|
||||||
|
# CONFIG_KINETIS_RNGB is not set
|
||||||
# CONFIG_KINETIS_FLEXCAN0 is not set
|
# CONFIG_KINETIS_FLEXCAN0 is not set
|
||||||
# CONFIG_KINETIS_FLEXCAN1 is not set
|
# CONFIG_KINETIS_FLEXCAN1 is not set
|
||||||
# CONFIG_KINETIS_SPI0 is not set
|
# CONFIG_KINETIS_SPI0 is not set
|
||||||
@ -312,7 +314,14 @@ CONFIG_ARCH_HAVE_IRQBUTTONS=y
|
|||||||
# Board-Specific Options
|
# Board-Specific Options
|
||||||
#
|
#
|
||||||
# CONFIG_BOARD_CRASHDUMP is not set
|
# CONFIG_BOARD_CRASHDUMP is not set
|
||||||
# CONFIG_LIB_BOARDCTL is not set
|
CONFIG_LIB_BOARDCTL=y
|
||||||
|
# CONFIG_BOARDCTL_RESET is not set
|
||||||
|
# CONFIG_BOARDCTL_UNIQUEID is not set
|
||||||
|
# CONFIG_BOARDCTL_TSCTEST is not set
|
||||||
|
# CONFIG_BOARDCTL_ADCTEST is not set
|
||||||
|
# CONFIG_BOARDCTL_PWMTEST is not set
|
||||||
|
# CONFIG_BOARDCTL_GRAPHICS is not set
|
||||||
|
# CONFIG_BOARDCTL_IOCTL is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# RTOS Features
|
# RTOS Features
|
||||||
@ -545,6 +554,7 @@ CONFIG_SYSLOG_SERIAL_CONSOLE=y
|
|||||||
CONFIG_SYSLOG_CONSOLE=y
|
CONFIG_SYSLOG_CONSOLE=y
|
||||||
# CONFIG_SYSLOG_NONE is not set
|
# CONFIG_SYSLOG_NONE is not set
|
||||||
# CONFIG_SYSLOG_FILE is not set
|
# CONFIG_SYSLOG_FILE is not set
|
||||||
|
# CONFIG_SYSLOG_CHARDEV is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Networking Support
|
# Networking Support
|
||||||
@ -584,7 +594,15 @@ CONFIG_FS_FAT=y
|
|||||||
# CONFIG_FS_ROMFS is not set
|
# CONFIG_FS_ROMFS is not set
|
||||||
# CONFIG_FS_TMPFS is not set
|
# CONFIG_FS_TMPFS is not set
|
||||||
# CONFIG_FS_SMARTFS is not set
|
# CONFIG_FS_SMARTFS is not set
|
||||||
# CONFIG_FS_PROCFS is not set
|
CONFIG_FS_PROCFS=y
|
||||||
|
CONFIG_FS_PROCFS_REGISTER=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# Exclude individual procfs entries
|
||||||
|
#
|
||||||
|
# CONFIG_FS_PROCFS_EXCLUDE_PROCESS is not set
|
||||||
|
# CONFIG_FS_PROCFS_EXCLUDE_UPTIME is not set
|
||||||
|
# CONFIG_FS_PROCFS_EXCLUDE_MOUNTS is not set
|
||||||
# CONFIG_FS_UNIONFS is not set
|
# CONFIG_FS_UNIONFS is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -730,6 +748,7 @@ CONFIG_EXAMPLES_NSH=y
|
|||||||
# CONFIG_EXAMPLES_TELNETD is not set
|
# CONFIG_EXAMPLES_TELNETD is not set
|
||||||
# CONFIG_EXAMPLES_TIFF is not set
|
# CONFIG_EXAMPLES_TIFF is not set
|
||||||
# CONFIG_EXAMPLES_TOUCHSCREEN is not set
|
# CONFIG_EXAMPLES_TOUCHSCREEN is not set
|
||||||
|
# CONFIG_EXAMPLES_USBSERIAL is not set
|
||||||
# CONFIG_EXAMPLES_USBTERM is not set
|
# CONFIG_EXAMPLES_USBTERM is not set
|
||||||
# CONFIG_EXAMPLES_WATCHDOG is not set
|
# CONFIG_EXAMPLES_WATCHDOG is not set
|
||||||
# CONFIG_EXAMPLES_WEBSERVER is not set
|
# CONFIG_EXAMPLES_WEBSERVER is not set
|
||||||
@ -829,7 +848,6 @@ CONFIG_NSH_DISABLE_LOSMART=y
|
|||||||
# CONFIG_NSH_DISABLE_MV is not set
|
# CONFIG_NSH_DISABLE_MV is not set
|
||||||
# CONFIG_NSH_DISABLE_MW is not set
|
# CONFIG_NSH_DISABLE_MW is not set
|
||||||
# CONFIG_NSH_DISABLE_PS is not set
|
# CONFIG_NSH_DISABLE_PS is not set
|
||||||
# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set
|
|
||||||
# CONFIG_NSH_DISABLE_PUT is not set
|
# CONFIG_NSH_DISABLE_PUT is not set
|
||||||
# CONFIG_NSH_DISABLE_PWD is not set
|
# CONFIG_NSH_DISABLE_PWD is not set
|
||||||
# CONFIG_NSH_DISABLE_RM is not set
|
# CONFIG_NSH_DISABLE_RM is not set
|
||||||
@ -853,6 +871,7 @@ CONFIG_NSH_MMCSDMINOR=0
|
|||||||
CONFIG_NSH_CMDOPT_DF_H=y
|
CONFIG_NSH_CMDOPT_DF_H=y
|
||||||
CONFIG_NSH_CODECS_BUFSIZE=128
|
CONFIG_NSH_CODECS_BUFSIZE=128
|
||||||
CONFIG_NSH_CMDOPT_HEXDUMP=y
|
CONFIG_NSH_CMDOPT_HEXDUMP=y
|
||||||
|
CONFIG_NSH_PROC_MOUNTPOINT="/proc"
|
||||||
CONFIG_NSH_FILEIOSIZE=512
|
CONFIG_NSH_FILEIOSIZE=512
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -867,7 +886,7 @@ CONFIG_NSH_FILEIOSIZE=512
|
|||||||
#
|
#
|
||||||
CONFIG_NSH_CONSOLE=y
|
CONFIG_NSH_CONSOLE=y
|
||||||
# CONFIG_NSH_ALTCONDEV is not set
|
# CONFIG_NSH_ALTCONDEV is not set
|
||||||
# CONFIG_NSH_ARCHINIT is not set
|
CONFIG_NSH_ARCHINIT=y
|
||||||
# CONFIG_NSH_LOGIN is not set
|
# CONFIG_NSH_LOGIN is not set
|
||||||
# CONFIG_NSH_CONSOLE_LOGIN is not set
|
# CONFIG_NSH_CONSOLE_LOGIN is not set
|
||||||
|
|
||||||
|
@ -49,6 +49,65 @@
|
|||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
|
/* Application Configuration ********************************************************/
|
||||||
|
|
||||||
|
/* Assume we have everything */
|
||||||
|
|
||||||
|
#define HAVE_PROC 1
|
||||||
|
#define NSH_HAVEUSBDEV 1
|
||||||
|
#define NSH_HAVEMMCSD 1
|
||||||
|
|
||||||
|
/* Automount procfs */
|
||||||
|
|
||||||
|
#if !defined(CONFIG_FS_PROCFS)
|
||||||
|
# undef HAVE_PROC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_PROC) && defined(CONFIG_DISABLE_MOUNTPOINT)
|
||||||
|
# warning Mountpoints disabled. No procfs support
|
||||||
|
# undef HAVE_PROC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_NSH_PROC_MOUNTPOINT)
|
||||||
|
# define PROCFS_MOUNTPOUNT CONFIG_NSH_PROC_MOUNTPOINT
|
||||||
|
#else
|
||||||
|
# define PROCFS_MOUNTPOUNT "/proc"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* SD card support */
|
||||||
|
|
||||||
|
#define MMCSD_SLOTNO 0
|
||||||
|
|
||||||
|
/* Can't support MMC/SD features if mountpoints are disabled or if SDHC support
|
||||||
|
* is not enabled.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_KINETIS_SDHC)
|
||||||
|
# undef NSH_HAVEMMCSD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NSH_HAVEMMCSD
|
||||||
|
# if defined(CONFIG_NSH_MMCSDSLOTNO) && CONFIG_NSH_MMCSDSLOTNO != 0
|
||||||
|
# error "Only one MMC/SD slot, slot 0"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* We expect to receive GPIO interrupts for card insertion events */
|
||||||
|
|
||||||
|
# ifndef CONFIG_GPIO_IRQ
|
||||||
|
# error "CONFIG_GPIO_IRQ required for card detect interrupt"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef CONFIG_KINETIS_PORTEINTS
|
||||||
|
# error "CONFIG_KINETIS_PORTEINTS required for card detect interrupt"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Can't support USB features if USB is not enabled */
|
||||||
|
|
||||||
|
#ifndef CONFIG_USBDEV
|
||||||
|
# undef NSH_HAVEUSBDEV
|
||||||
|
#endif
|
||||||
|
|
||||||
/* How many SPI modules does this chip support? The LM3S6918 supports 2 SPI
|
/* How many SPI modules does this chip support? The LM3S6918 supports 2 SPI
|
||||||
* modules (others may support more -- in such case, the following must be
|
* modules (others may support more -- in such case, the following must be
|
||||||
* expanded).
|
* expanded).
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <sys/mount.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
@ -54,58 +55,6 @@
|
|||||||
|
|
||||||
#if defined(CONFIG_LIB_BOARDCTL) || defined(CONFIG_BOARD_INITIALIZE)
|
#if defined(CONFIG_LIB_BOARDCTL) || defined(CONFIG_BOARD_INITIALIZE)
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
/* Configuration ************************************************************/
|
|
||||||
|
|
||||||
/* PORT and SLOT number probably depend on the board configuration */
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_BOARD_FREEDOM_K64F
|
|
||||||
# define NSH_HAVEUSBDEV 1
|
|
||||||
# define NSH_HAVEMMCSD 1
|
|
||||||
# if defined(CONFIG_NSH_MMCSDSLOTNO) && CONFIG_NSH_MMCSDSLOTNO != 0
|
|
||||||
# error "Only one MMC/SD slot, slot 0"
|
|
||||||
# undef CONFIG_NSH_MMCSDSLOTNO
|
|
||||||
# endif
|
|
||||||
# ifndef CONFIG_NSH_MMCSDSLOTNO
|
|
||||||
# define CONFIG_NSH_MMCSDSLOTNO 0
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
/* Add configuration for new Kinetis boards here */
|
|
||||||
# error "Unrecognized Kinetis board"
|
|
||||||
# undef NSH_HAVEUSBDEV
|
|
||||||
# undef NSH_HAVEMMCSD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Can't support USB features if USB is not enabled */
|
|
||||||
|
|
||||||
#ifndef CONFIG_USBDEV
|
|
||||||
# undef NSH_HAVEUSBDEV
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Can't support MMC/SD features if mountpoints are disabled or if SDHC support
|
|
||||||
* is not enabled.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_KINETIS_SDHC)
|
|
||||||
# undef NSH_HAVEMMCSD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CONFIG_NSH_MMCSDMINOR
|
|
||||||
# define CONFIG_NSH_MMCSDMINOR 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* We expect to receive GPIO interrupts for card insertion events */
|
|
||||||
|
|
||||||
#ifndef CONFIG_GPIO_IRQ
|
|
||||||
# error "CONFIG_GPIO_IRQ required for card detect interrupt"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CONFIG_KINETIS_PORTEINTS
|
|
||||||
# error "CONFIG_KINETIS_PORTEINTS required for card detect interrupt"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -199,9 +148,24 @@ static int k64_cdinterrupt(int irq, FAR void *context)
|
|||||||
|
|
||||||
int k64_bringup(void)
|
int k64_bringup(void)
|
||||||
{
|
{
|
||||||
#ifdef NSH_HAVEMMCSD
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
#ifdef HAVE_PROC
|
||||||
|
/* Mount the proc filesystem */
|
||||||
|
|
||||||
|
syslog(LOG_INFO, "Mounting procfs to /proc\n");
|
||||||
|
|
||||||
|
ret = mount(NULL, PROCFS_MOUNTPOUNT, "procfs", 0, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
syslog(LOG_ERR,
|
||||||
|
"ERROR: Failed to mount the PROC filesystem: %d (%d)\n",
|
||||||
|
ret, errno);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NSH_HAVEMMCSD
|
||||||
/* Configure GPIO pins */
|
/* Configure GPIO pins */
|
||||||
|
|
||||||
/* Attached the card detect interrupt (but don't enable it yet) */
|
/* Attached the card detect interrupt (but don't enable it yet) */
|
||||||
@ -211,19 +175,18 @@ int k64_bringup(void)
|
|||||||
|
|
||||||
/* Configure the write protect GPIO */
|
/* Configure the write protect GPIO */
|
||||||
|
|
||||||
kinetis_pinconfig(GPIO_SD_WRPROTECT);
|
//kinetis_pinconfig(GPIO_SD_WRPROTECT);
|
||||||
|
|
||||||
/* Mount the SDHC-based MMC/SD block driver */
|
/* Mount the SDHC-based MMC/SD block driver */
|
||||||
/* First, get an instance of the SDHC interface */
|
/* First, get an instance of the SDHC interface */
|
||||||
|
|
||||||
syslog(LOG_INFO, "Initializing SDHC slot %d\n",
|
syslog(LOG_INFO, "Initializing SDHC slot %d\n", MMCSD_SLOTNO);
|
||||||
CONFIG_NSH_MMCSDSLOTNO);
|
|
||||||
|
|
||||||
g_nsh.sdhc = sdhc_initialize(CONFIG_NSH_MMCSDSLOTNO);
|
g_nsh.sdhc = sdhc_initialize(MMCSD_SLOTNO);
|
||||||
if (!g_nsh.sdhc)
|
if (!g_nsh.sdhc)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ERROR: Failed to initialize SDHC slot %d\n",
|
syslog(LOG_ERR, "ERROR: Failed to initialize SDHC slot %d\n",
|
||||||
CONFIG_NSH_MMCSDSLOTNO);
|
MMCSD_SLOTNO);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +212,8 @@ int k64_bringup(void)
|
|||||||
|
|
||||||
kinetis_pinirqenable(GPIO_SD_CARDDETECT);
|
kinetis_pinirqenable(GPIO_SD_CARDDETECT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
UNUSED(ret);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1691,6 +1691,11 @@ static int smartfs_unlink(struct inode *mountpt, const char *relpath)
|
|||||||
ret = OK;
|
ret = OK;
|
||||||
|
|
||||||
errout_with_semaphore:
|
errout_with_semaphore:
|
||||||
|
if (entry.name != NULL)
|
||||||
|
{
|
||||||
|
kmm_free(entry.name);
|
||||||
|
}
|
||||||
|
|
||||||
smartfs_semgive(fs);
|
smartfs_semgive(fs);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1856,6 +1861,11 @@ int smartfs_rmdir(struct inode *mountpt, const char *relpath)
|
|||||||
ret = OK;
|
ret = OK;
|
||||||
|
|
||||||
errout_with_semaphore:
|
errout_with_semaphore:
|
||||||
|
if (entry.name != NULL)
|
||||||
|
{
|
||||||
|
kmm_free(entry.name);
|
||||||
|
}
|
||||||
|
|
||||||
smartfs_semgive(fs);
|
smartfs_semgive(fs);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user