diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2010-04-28 01:25:38 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2010-04-28 01:25:38 +0000 |
commit | 68e3b7182d88efaefabe22a9ce73ea3509f2f5a2 (patch) | |
tree | 9951bbca344a7e46b79f3cb2c74752d9503dce0d /nuttx | |
parent | a93a76bd76b69717c5adc252665bcfde94a0436f (diff) | |
download | px4-nuttx-68e3b7182d88efaefabe22a9ce73ea3509f2f5a2.tar.gz px4-nuttx-68e3b7182d88efaefabe22a9ce73ea3509f2f5a2.tar.bz2 px4-nuttx-68e3b7182d88efaefabe22a9ce73ea3509f2f5a2.zip |
Add phy read/write routines
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2635 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rwxr-xr-x | nuttx/drivers/net/enc28j60.c | 129 | ||||
-rwxr-xr-x | nuttx/drivers/net/enc28j60.h | 84 |
2 files changed, 176 insertions, 37 deletions
diff --git a/nuttx/drivers/net/enc28j60.c b/nuttx/drivers/net/enc28j60.c index 5f439b352..b0171e794 100755 --- a/nuttx/drivers/net/enc28j60.c +++ b/nuttx/drivers/net/enc28j60.c @@ -201,9 +201,9 @@ static void enc_wdgreg2(FAR struct enc_driver_s *priv, uint8_t cmd, uint8_t wrdata); static void enc_setbank(FAR struct enc_driver_s *priv, uint8_t bank); static uint8_t enc_rdbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg); -static uint8_t enc_wrbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg, +static void enc_wrbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg, uint8_t wrdata); -static uint8_t enc_rdphymac(FAR struct enc_driver_s *priv, uint8_t ctrlreg); +static uint8_t enc_rdmreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg); /* SPI buffer transfers */ @@ -355,9 +355,12 @@ static uint8_t enc_rdgreg2(FAR struct enc_driver_s *priv, uint8_t cmd) enc_select(spi); - /* Send the read command and (maybe collect the return data) */ + /* Send the read command and collect the data. The sequence requires + * 16-clocks: 8 to clock out the cmd + 8 to clock in the data. + */ - rddata = SPI_SEND(spi, cmd); + (void)SPI_SEND(spi, cmd); /* Clock out the command */ + rddata = SPI_SEND(spi, 0); /* Clock in the data */ /* De-select ENC28J60 chip */ @@ -386,13 +389,12 @@ static void enc_wdgreg2(FAR struct enc_driver_s *priv, uint8_t cmd, enc_select(spi); - /* Send the write command */ - - (void)SPI_SEND(spi, cmd); - - /* Send the data byte */ + /* Send the write command and data. The sequence requires 16-clocks: + * 8 to clock out the cmd + 8 to clock out the data. + */ - (void)SPI_SEND(spi, wrdata); + (void)SPI_SEND(spi, cmd); /* Clock out the command */ + (void)SPI_SEND(spi, wrdata); /* Clock out the data */ /* De-select ENC28J60 chip. */ @@ -437,7 +439,7 @@ static void enc_setbank(FAR struct enc_driver_s *priv, uint8_t bank) * Function: enc_rdbreg * * Description: - * Set the bank for these next control register access. + * Read from a banked control register using the RCR command. * ****************************************************************************/ @@ -453,13 +455,16 @@ static uint8_t enc_rdbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg) enc_select(spi); - /* set the bank */ + /* Set the bank */ enc_setbank(priv, GETBANK(ctrlreg)); - /* Send the read command and collect the return data. */ + /* Send the RCR command and collect the data. The sequence requires + * 16-clocks: 8 to clock out the cmd + 8 to clock in the data. + */ - rddata = SPI_SEND(spi, ENC_RCR | GETADDR(ctrlreg)); + (void)SPI_SEND(spi, ENC_RCR | GETADDR(ctrlreg)); /* Clock out the command */ + rddata = SPI_SEND(spi, 0); /* Clock in the data */ /* De-select ENC28J60 chip */ @@ -468,7 +473,7 @@ static uint8_t enc_rdbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg) } /**************************************************************************** - * Function: enc_rdphymac + * Function: enc_rdmreg * * Description: * Somewhat different timing is required to read from any PHY or MAC @@ -477,7 +482,7 @@ static uint8_t enc_rdbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg) * ****************************************************************************/ -static uint8_t enc_rdphymac(FAR struct enc_driver_s *priv, uint8_t ctrlreg) +static uint8_t enc_rdmreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg) { FAR struct spi_dev_s *spi; uint8_t rddata; @@ -493,13 +498,14 @@ static uint8_t enc_rdphymac(FAR struct enc_driver_s *priv, uint8_t ctrlreg) enc_setbank(priv, GETBANK(ctrlreg)); - /* Send the read command (discarding the return data) */ - - (void)SPI_SEND(spi, ENC_RCR | GETADDR(ctrlreg)); - - /* Do an extra transfer to get the data from the MAC or PHY */ + /* Send the RCR command and collect the data. The sequence requires + * 24-clocks: 8 to clock out the cmd, 8 dummy bits, and 8 to clock in + the data. + */ - rddata = SPI_SEND(spi, 0); + (void)SPI_SEND(spi, ENC_RCR | GETADDR(ctrlreg)); /* Clock out the command */ + (void)SPI_SEND(spi,0); /* Clock in the dummy byte */ + rddata = SPI_SEND(spi, 0); /* Clock in the PHY/MAC data */ /* De-select ENC28J60 chip */ @@ -508,15 +514,15 @@ static uint8_t enc_rdphymac(FAR struct enc_driver_s *priv, uint8_t ctrlreg) } /**************************************************************************** - * Function: enc_rwrbreg + * Function: enc_wrbreg * * Description: - * Set the bank for these next control register access. + * Write to a banked control register using the WCR command. * ****************************************************************************/ -static void enc_rwrbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg, - uint8_t wrdata) +static void enc_wrbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg, + uint8_t wrdata) { FAR struct spi_dev_s *spi; @@ -531,13 +537,12 @@ static void enc_rwrbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg, enc_setbank(priv, GETBANK(ctrlreg)); - /* Send the write command */ - - (void)SPI_SEND(spi, ENC_WCR | GETADDR(ctrlreg)); - - /* Send the data byte */ + /* Send the WCR command and data. The sequence requires 16-clocks: + * 8 to clock out the cmd + 8 to clock out the data. + */ - (void)SPI_SEND(spi, wrdata); + (void)SPI_SEND(spi, ENC_WCR | GETADDR(ctrlreg)); /* Clock out the command */ + (void)SPI_SEND(spi, wrdata); /* Clock out the data */ /* De-select ENC28J60 chip. */ @@ -611,6 +616,63 @@ static void enc_wrbuffer(FAR struct enc_driver_s *priv, } /**************************************************************************** + * Function: enc_rdphy + * + * Description: + * Read 16-bits of PHY data. + * + ****************************************************************************/ + +static uint16_t enc_rdphy(FAR struct enc_driver_s *priv, uint8_t phyaddr) +{ + uint16_t data; + + /* Set the PHY address (and start the PHY read operation) */ + + enc_wrbreg(priv, ENC_MIREGADR, phyaddr); + enc_wrbreg(priv, ENC_MICMD, MICMD_MIIRD); + + /* Wait until the PHY read completes */ + + while ((enc_rdmreg(priv, ENC_MISTAT) & MISTAT_BUSY) != 0 ); + + /* Terminate reading */ + + enc_wrbreg(priv, ENC_MICMD, 0x00); + + /* Get data value */ + + data = (uint16_t)enc_rdmreg(priv, ENC_MIRDL); + data |= (uint16_t)enc_rdmreg(priv, ENC_MIRDH) << 8; + return data; +} + +/**************************************************************************** + * Function: enc_wrphy + * + * Description: + * write 16-bits of PHY data. + * + ****************************************************************************/ + +static void enc_wrphy(FAR struct enc_driver_s *priv, uint8_t phyaddr, + uint16_t phydata) +{ + /* Set the PHY register address */ + + enc_wrbreg(priv, ENC_MIREGADR, phyaddr); + + /* Write the PHY data */ + + enc_wrbreg(priv, ENC_MIWRL, phydata); + enc_wrbreg(priv, ENC_MIWRH, phydata >> 8); + + /* Wait until the PHY write completes */ + + while ((enc_rdmreg(priv, ENC_MISTAT) & MISTAT_BUSY) != 0); +} + +/**************************************************************************** * Function: enc_transmit * * Description: @@ -776,7 +838,8 @@ static void enc_txerif(FAR struct enc_driver_s *priv) enc_bfsgreg(priv, ENC_ECON1, ECON1_TXRST); enc_bfcgreg(priv, ENC_ECON1, ECON1_TXRST | ECON1_TXRTS); - /* Here we really should re-transmit: + /* Here we really should re-transmit (I fact, if we want half duplex to + * work right, then it is necessary to do this!): * * 1. Read the TSV: * - Read ETXNDL to get the end pointer diff --git a/nuttx/drivers/net/enc28j60.h b/nuttx/drivers/net/enc28j60.h index f0e00687a..f79f073bb 100755 --- a/nuttx/drivers/net/enc28j60.h +++ b/nuttx/drivers/net/enc28j60.h @@ -225,12 +225,24 @@ #define ENC_EPKTCNT REGADDR(0x19, 1) /* Ethernet Packet Count */ /* 0x1a: Reserved */ /* 0x1b-0x1f: EIE, EIR, ESTAT, ECON2, ECON1 */ + +/* Receive Filter Configuration Bit Definitions */ + +#define ERXFCON_BCEN (1 << 0) /* Bit 0: Broadcast Filter Enable */ +#define ERXFCON_MCEN (1 << 1) /* Bit 1: Multicast Filter Enable */ +#define ERXFCON_HTEN (1 << 2) /* Bit 2: Hash Table Filter Enable */ +#define ERXFCON_MPEN (1 << 3) /* Bit 3: Magic Packet Filter Enable */ +#define ERXFCON_PMEN (1 << 4) /* Bit 4: Pattern Match Filter Enable */ +#define ERXFCON_CRCEN (1 << 5) /* Bit 5: Post-Filter CRC Check Enable */ +#define ERXFCON_ANDOR (1 << 6) /* Bit 6: AND/OR Filter Select */ +#define ERXFCON_UCEN (1 << 7) /* Bit 7: Unicast Filter Enable */ + /* Bank 2 Control Register Addresses */ -#define ENC_MACON1 REGADDR(0x00, 2) /* MAC control 1 */ -#define ENC_MACON2 REGADDR(0x01, 2) /* MAC control 2 */ -#define ENC_MACON3 REGADDR(0x02, 2) /* MAC control 3 */ -#define ENC_MACON4 REGADDR(0x03, 2) /* MAC control 4 */ +#define ENC_MACON1 REGADDR(0x00, 2) /* MAC Control 1 */ + /* 0x01: Reserved */ +#define ENC_MACON3 REGADDR(0x02, 2) /* MAC Control 3 */ +#define ENC_MACON4 REGADDR(0x03, 2) /* MAC Control 4 */ #define ENC_MABBIPG REGADDR(0x04, 2) /* Back-to-Back Inter-Packet Gap (BBIPG<6:0>) */ /* 0x05: Reserved */ #define ENC_MAIPGL REGADDR(0x06, 2) /* Non-Back-to-Back Inter-Packet Gap Low Byte (MAIPGL<6:0>) */ @@ -250,6 +262,37 @@ #define ENC_MIRDH REGADDR(0x19, 2) /* MII Read Data High Byte(MIRD<15:8>) */ /* 0x1a: Reserved */ /* 0x1b-0x1f: EIE, EIR, ESTAT, ECON2, ECON1 */ + +/* MAC Control 1 Register Bit Definitions */ + +#define MACON1_MARXEN (1 << 0) /* Bit 0: MAC Receive Enable */ +#define MACON1_PASSALL (1 << 1) /* Bit 1: Pass All Received Frames Enable */ +#define MACON1_RXPAUS (1 << 2) /* Bit 2: Pause Control Frame Reception Enable */ +#define MACON1_TXPAUS (1 << 3) /* Bit 3: Pause Control Frame Transmission Enable */ + /* Bits 4-7: Unimplemented or reserved */ + +/* MAC Control 1 Register Bit Definitions */ + +#define MACON3_FULDPX (1 << 0) /* Bit 0: MAC Full-Duplex Enable */ +#define MACON3_FRMLNEN (1 << 1) /* Bit 1: Frame Length Checking Enable */ +#define MACON3_HFRMLEN (1 << 2) /* Bit 2: Huge Frame Enable */ +#define MACON3_PHDRLEN (1 << 3) /* Bit 3: Proprietary Header Enable */ +#define MACON3_TXCRCEN (1 << 4) /* Bit 4: Transmit CRC Enable */ +#define MACON3_PADCFG0 (1 << 5) /* Bit 5: Automatic Pad and CRC Configuration */ +#define MACON3_PADCFG1 (1 << 6) /* Bit 6: " " " " " " " " " " */ +#define MACON3_PADCFG2 (1 << 7) /* Bit 7: " " " " " " " " " " */ + +/* MAC Control 1 Register Bit Definitions */ + +#define MACON4_NOBKOFF (1 << 4) /* Bit 4: No Backoff Enable */ +#define MACON4_BPEN (1 << 5) /* Bit 5: No Backoff During Backpressure Enable */ +#define MACON4_DEFER (1 << 6) /* Bit 6: Defer Transmission Enable bit */ + +/* MII Command Register Bit Definitions */ + +#define MICMD_MIIRD (1 << 0) /* Bit 0: MII Read Enable */ +#define MICMD_MIISCAN (1 << 1) /* Bit 1: MII Scan Enable */ + /* Bank 3 Control Register Addresses */ #define ENC_MAADR5 REGADDR(0x00, 3) /* MAC Address Byte 5 (MAADR<15:8>) */ @@ -274,6 +317,31 @@ /* 0x1a: Reserved */ /* 0x1b-0x1f: EIE, EIR, ESTAT, ECON2, ECON1 */ +/* Built-in Self-Test Control Register Bit Definitions */ + +#define EBSTCON_BISTST (1 << 0) /* Bit 0: Built-in Self-Test Start/Busy */ +#define EBSTCON_TME (1 << 1) /* Bit 1: Test Mode Enable */ +#define EBSTCON_TMSEL0 (1 << 2) /* Bit 2: Test Mode Select */ +#define EBSTCON_TMSEL1 (1 << 3) /* Bit 3: " " " " " " */ +#define EBSTCON_PSEL (1 << 4) /* Bit 4: Port Select */ +#define EBSTCON_PSV0 (1 << 5) /* Bit 5: Pattern Shift Value */ +#define EBSTCON_PSV1 (1 << 6) /* Bit 6: " " " " " */ +#define EBSTCON_PSV2 (1 << 7) /* Bit 7: " " " " " */ + +/* MII Status Register Register Bit Definitions */ + +#define MISTAT_BUSY (1 << 0) /* Bit 0: MII Management Busy */ +#define MISTAT_SCAN (1 << 1) /* Bit 1: MII Management Scan Operation */ +#define MISTAT_NVALID (1 << 2) /* Bit 2: MII Management Read Data Not Valid */ + /* Bits 3-7: Reserved or unimplemented */ + +/* Ethernet Flow Control Register Bit Definitions */ + +#define EFLOCON_FCEN0 (1 << 0) /* Bit 0: Flow Control Enable */ +#define EFLOCON_FCEN1 (1 << 1) /* Bit 1: " " " " " " */ +#define EFLOCON_FULDPXS (1 << 2) /* Bit 2: Read-Only MAC Full-Duplex Shadow */ + /* Bits 3-7: Reserved or unimplemented */ + /* PHY Registers ************************************************************/ #define ENC_PHCON1 (0x00) /* PHY Control Register 1 */ @@ -328,6 +396,7 @@ /* PHLCON Regiser Bit Definitions */ + /* Bit 0: Reserved */ #define PHLCON_STRCH (1 << 1) /* Bit 1: LED Pulse Stretching Enable */ #define PHLCON_LFRQ0 (1 << 2) /* Bit 2: LED Pulse Stretch Time Configuration */ #define PHLCON_LFRQ1 (1 << 3) /* Bit 3: " " " " " " " " " */ @@ -340,6 +409,13 @@ #define PHLCON_LACFG2 (1 << 10) /* Bit 10: " " " " */ #define PHLCON_LACFG3 (1 << 11) /* Bit 11: " " " " */ +/* Packet Control Bits Definitions ******************************************/ + +#define PKTCTRL_POVERRIDE (1 << 0) /* Bit 0: Per Packet Override */ +#define PKTCTRL_PCRCEN (1 << 1) /* Bit 1: Per Packet CRC Enable */ +#define PKTCTRL_PPADEN (1 << 2) /* Bit 2: Per Packet Padding Enable */ +#define PKTCTRL_PHUGEEN (1 << 3) /* Bit 3: Per Packet Huge Frame Enable */ + /**************************************************************************** * Public Types ****************************************************************************/ |