From 9b4319f735bf1c209f51ce2c5e7fd642ceb60909 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 21 Aug 2009 11:10:09 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1099 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/io/platforms/AT91SAM7X/mii.h | 156 +++++++++++ os/io/platforms/AT91SAM7X/pal_lld.c | 116 ++++++++ os/io/platforms/AT91SAM7X/pal_lld.h | 245 +++++++++++++++++ os/io/platforms/AT91SAM7X/platform.dox | 73 +++++ os/io/platforms/AT91SAM7X/sam7x_emac.c | 418 +++++++++++++++++++++++++++++ os/io/platforms/AT91SAM7X/sam7x_emac.h | 93 +++++++ os/ports/GCC/ARM7/AT91SAM7X/mii.h | 156 ----------- os/ports/GCC/ARM7/AT91SAM7X/pal_lld.c | 116 -------- os/ports/GCC/ARM7/AT91SAM7X/pal_lld.h | 245 ----------------- os/ports/GCC/ARM7/AT91SAM7X/port.dox | 73 ----- os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.c | 418 ----------------------------- os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.h | 93 ------- os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.c | 224 ---------------- os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.h | 86 ------ 14 files changed, 1101 insertions(+), 1411 deletions(-) create mode 100644 os/io/platforms/AT91SAM7X/mii.h create mode 100644 os/io/platforms/AT91SAM7X/pal_lld.c create mode 100644 os/io/platforms/AT91SAM7X/pal_lld.h create mode 100644 os/io/platforms/AT91SAM7X/platform.dox create mode 100644 os/io/platforms/AT91SAM7X/sam7x_emac.c create mode 100644 os/io/platforms/AT91SAM7X/sam7x_emac.h delete mode 100644 os/ports/GCC/ARM7/AT91SAM7X/mii.h delete mode 100644 os/ports/GCC/ARM7/AT91SAM7X/pal_lld.c delete mode 100644 os/ports/GCC/ARM7/AT91SAM7X/pal_lld.h delete mode 100644 os/ports/GCC/ARM7/AT91SAM7X/port.dox delete mode 100644 os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.c delete mode 100644 os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.h delete mode 100644 os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.c delete mode 100644 os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.h diff --git a/os/io/platforms/AT91SAM7X/mii.h b/os/io/platforms/AT91SAM7X/mii.h new file mode 100644 index 000000000..4ec25667a --- /dev/null +++ b/os/io/platforms/AT91SAM7X/mii.h @@ -0,0 +1,156 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + * Parts of this file are borrowed by the Linux include file linux/mii.h: + * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com) + */ + +#ifndef _MII_H_ +#define _MII_H_ + +/* Generic MII registers. */ +#define MII_BMCR 0x00 /* Basic mode control register */ +#define MII_BMSR 0x01 /* Basic mode status register */ +#define MII_PHYSID1 0x02 /* PHYS ID 1 */ +#define MII_PHYSID2 0x03 /* PHYS ID 2 */ +#define MII_ADVERTISE 0x04 /* Advertisement control reg */ +#define MII_LPA 0x05 /* Link partner ability reg */ +#define MII_EXPANSION 0x06 /* Expansion register */ +#define MII_CTRL1000 0x09 /* 1000BASE-T control */ +#define MII_STAT1000 0x0a /* 1000BASE-T status */ +#define MII_ESTATUS 0x0f /* Extended Status */ +#define MII_DCOUNTER 0x12 /* Disconnect counter */ +#define MII_FCSCOUNTER 0x13 /* False carrier counter */ +#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ +#define MII_RERRCOUNTER 0x15 /* Receive error counter */ +#define MII_SREVISION 0x16 /* Silicon revision */ +#define MII_RESV1 0x17 /* Reserved... */ +#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ +#define MII_PHYADDR 0x19 /* PHY address */ +#define MII_RESV2 0x1a /* Reserved... */ +#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */ +#define MII_NCONFIG 0x1c /* Network interface config */ + +/* Basic mode control register. */ +#define BMCR_RESV 0x003f /* Unused... */ +#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ +#define BMCR_CTST 0x0080 /* Collision test */ +#define BMCR_FULLDPLX 0x0100 /* Full duplex */ +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ +#define BMCR_RESET 0x8000 /* Reset the DP83840 */ + +/* Basic mode status register. */ +#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ +#define BMSR_JCD 0x0002 /* Jabber detected */ +#define BMSR_LSTATUS 0x0004 /* Link status */ +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ +#define BMSR_RFAULT 0x0010 /* Remote fault detected */ +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ +#define BMSR_RESV 0x00c0 /* Unused... */ +#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ +#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */ +#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */ +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ +#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ + +/* Advertisement control register. */ +#define ADVERTISE_SLCT 0x001f /* Selector bits */ +#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ +#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */ +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ +#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */ +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ +#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */ +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ +#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */ +#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ +#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */ +#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */ +#define ADVERTISE_RESV 0x1000 /* Unused... */ +#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ +#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ +#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ + +#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \ + ADVERTISE_CSMA) +#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \ + ADVERTISE_100HALF | ADVERTISE_100FULL) + +/* Link partner ability register. */ +#define LPA_SLCT 0x001f /* Same as advertise selector */ +#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ +#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */ +#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ +#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */ +#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ +#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */ +#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ +#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/ +#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */ +#define LPA_PAUSE_CAP 0x0400 /* Can pause */ +#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */ +#define LPA_RESV 0x1000 /* Unused... */ +#define LPA_RFAULT 0x2000 /* Link partner faulted */ +#define LPA_LPACK 0x4000 /* Link partner acked us */ +#define LPA_NPAGE 0x8000 /* Next page bit */ + +#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL) +#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) + +/* Expansion register for auto-negotiation. */ +#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */ +#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */ +#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */ +#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */ +#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */ +#define EXPANSION_RESV 0xffe0 /* Unused... */ + +#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */ +#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */ + +/* N-way test register. */ +#define NWAYTEST_RESV1 0x00ff /* Unused... */ +#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */ +#define NWAYTEST_RESV2 0xfe00 /* Unused... */ + +/* 1000BASE-T Control register */ +#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ +#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ + +/* 1000BASE-T Status register */ +#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */ +#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */ +#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */ +#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */ + +#define MII_DM9161_ID 0x0181b8a0 +#define MII_AM79C875_ID 0x00225540 +#define MII_MICREL_ID 0x00221610 + +#endif /* _MII_H_ */ diff --git a/os/io/platforms/AT91SAM7X/pal_lld.c b/os/io/platforms/AT91SAM7X/pal_lld.c new file mode 100644 index 000000000..6c8b26cda --- /dev/null +++ b/os/io/platforms/AT91SAM7X/pal_lld.c @@ -0,0 +1,116 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file os/ports/GCC/ARM7/AT91SAM7X/pal_lld.c + * @brief AT91SAM7X PIO low level driver code + * @addtogroup AT91SAM7X_PAL + * @{ + */ + +#include +#include + +/** + * @brief AT91SAM7X I/O ports configuration. + * @details PIO registers initialization. + * + * @param[in] config the AT91SAM7X ports configuration + */ +void _pal_lld_init(const AT91SAM7XPIOConfig *config) { + + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOA) | (1 << AT91C_ID_PIOB); + + /* + * PIOA setup. + */ + AT91C_BASE_PIOA->PIO_OER = config->P0Data.pusr; /* Pull-up as spec.*/ + AT91C_BASE_PIOA->PIO_ODR = ~config->P0Data.pusr; + AT91C_BASE_PIOA->PIO_PER = 0xFFFFFFFF; /* PIO enabled.*/ + AT91C_BASE_PIOA->PIO_ODSR = config->P0Data.odsr; /* Data as specified.*/ + AT91C_BASE_PIOA->PIO_OER = config->P0Data.osr; /* Dir. as specified.*/ + AT91C_BASE_PIOA->PIO_ODR = ~config->P0Data.osr; + AT91C_BASE_PIOA->PIO_IFDR = 0xFFFFFFFF; /* Filter disabled.*/ + AT91C_BASE_PIOA->PIO_IDR = 0xFFFFFFFF; /* Int. disabled.*/ + AT91C_BASE_PIOA->PIO_MDDR = 0xFFFFFFFF; /* Push Pull drive.*/ + AT91C_BASE_PIOA->PIO_ASR = 0xFFFFFFFF; /* Peripheral A.*/ + AT91C_BASE_PIOA->PIO_OWER = 0xFFFFFFFF; /* Write enabled.*/ + + /* + * PIOB setup. + */ + AT91C_BASE_PIOB->PIO_OER = config->P0Data.pusr; /* Pull-up as spec.*/ + AT91C_BASE_PIOB->PIO_ODR = ~config->P0Data.pusr; + AT91C_BASE_PIOB->PIO_PER = 0xFFFFFFFF; /* PIO enabled.*/ + AT91C_BASE_PIOB->PIO_ODSR = config->P1Data.odsr; /* Data as specified.*/ + AT91C_BASE_PIOB->PIO_OER = config->P1Data.osr; /* Dir. as specified.*/ + AT91C_BASE_PIOB->PIO_ODR = ~config->P1Data.osr; + AT91C_BASE_PIOB->PIO_IFDR = 0xFFFFFFFF; /* Filter disabled.*/ + AT91C_BASE_PIOB->PIO_IDR = 0xFFFFFFFF; /* Int. disabled.*/ + AT91C_BASE_PIOB->PIO_MDDR = 0xFFFFFFFF; /* Push Pull drive.*/ + AT91C_BASE_PIOB->PIO_ASR = 0xFFFFFFFF; /* Peripheral A.*/ + AT91C_BASE_PIOB->PIO_OWER = 0xFFFFFFFF; /* Write enabled.*/ +} + +/** + * @brief Pads mode setup. + * @details This function programs a pads group belonging to the same port + * with the specified mode. + * + * @param[in] port the port identifier + * @param[in] mask the group mask + * @param[in] mode the mode + * + * @note This function is not meant to be invoked directly by the application + * code. + * @note @p PAL_MODE_RESET is implemented as input with pull-up. + * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with high + * state. + * @note @p PAL_MODE_OUTPUT_OPENDRAIN also enables the pull-up resistor. + */ +void _pal_lld_setgroupmode(ioportid_t port, + ioportmask_t mask, + uint_fast8_t mode) { + + switch (mode & PAL_MODE_MASK) { + case PAL_MODE_RESET: + case PAL_MODE_INPUT_PULLUP: + port->PIO_PPUER = mask; + port->PIO_ODR = mask; + break; + case PAL_MODE_INPUT: + port->PIO_PPUDR = mask; + port->PIO_ODR = mask; + break; + case PAL_MODE_UNCONNECTED: + port->PIO_SODR = mask; + /* Falls in */ + case PAL_MODE_OUTPUT_PUSHPULL: + port->PIO_PPUDR = mask; + port->PIO_OER = mask; + port->PIO_MDDR = mask; + break; + case PAL_MODE_OUTPUT_OPENDRAIN: + port->PIO_PPUER = mask; + port->PIO_OER = mask; + port->PIO_MDER = mask; + } +} + +/** @} */ diff --git a/os/io/platforms/AT91SAM7X/pal_lld.h b/os/io/platforms/AT91SAM7X/pal_lld.h new file mode 100644 index 000000000..1f50b5734 --- /dev/null +++ b/os/io/platforms/AT91SAM7X/pal_lld.h @@ -0,0 +1,245 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file os/ports/GCC/ARM7/AT91SAM7X/pal_lld.h + * @brief AT91SAM7X PIO low level driver header + * @addtogroup AT91SAM7X_PAL + * @{ + */ + +#ifndef _PAL_LLD_H_ +#define _PAL_LLD_H_ + +#include "at91lib/AT91SAM7X256.h" + +/*===========================================================================*/ +/* Unsupported modes and specific modes */ +/*===========================================================================*/ + +#undef PAL_MODE_INPUT_PULLDOWN + +/*===========================================================================*/ +/* I/O Ports Types and constants. */ +/*===========================================================================*/ + +/** + * @brief PIO port setup info. + */ +typedef struct { + /** Initial value for ODSR register (data).*/ + uint32_t odsr; + /** Initial value for OSR register (direction).*/ + uint32_t osr; + /** Initial value for PUSR register (Pull-ups).*/ + uint32_t pusr; +} at91sam7x_pio_setup_t; + +/** + * @brief AT91SAM7X PIO static initializer. + * @details An instance of this structure must be passed to @p palInit() at + * system startup time in order to initialized the digital I/O + * subsystem. This represents only the initial setup, specific pads + * or whole ports can be reprogrammed at later time. + */ +typedef struct { + /** @brief Port 0 setup data.*/ + at91sam7x_pio_setup_t P0Data; + /** @brief Port 1 setup data.*/ + at91sam7x_pio_setup_t P1Data; +} AT91SAM7XPIOConfig; + +/** + * @brief Width, in bits, of an I/O port. + */ +#define PAL_IOPORTS_WIDTH 32 + +/** + * @brief Digital I/O port sized unsigned type. + */ +typedef uint32_t ioportmask_t; + +/** + * @brief Port Identifier. + * @details This type can be a scalar or some kind of pointer, do not make + * any assumption about it, use the provided macros when populating + * variables of this type. + */ +typedef AT91PS_PIO ioportid_t; + +/*===========================================================================*/ +/* I/O Ports Identifiers. */ +/*===========================================================================*/ + +/** + * @brief PIO port A identifier. + */ +#define IOPORT_A AT91C_BASE_PIOA + +/** + * @brief PIO port B identifier. + */ +#define IOPORT_B AT91C_BASE_PIOB + +/*===========================================================================*/ +/* Implementation, some of the following macros could be implemented as */ +/* functions, if so please put them in a file named pal_lld.c. */ +/*===========================================================================*/ + +/** + * @brief Low level PAL subsystem initialization. + */ +#define pal_lld_init(config) _pal_lld_init(config) + +/** + * @brief Reads the physical I/O port states. + * @details This function is implemented by reading the PIO_PDSR register, the + * implementation has no side effects. + * + * @param[in] port the port identifier + * @return The port bits. + * + * @note This function is not meant to be invoked directly by the application + * code. + */ +#define pal_lld_readport(port) ((port)->PIO_PDSR) + +/** + * @brief Reads the output latch. + * @details This function is implemented by reading the PIO_ODSR register, the + * implementation has no side effects. + * + * @param[in] port the port identifier + * @return The latched logical states. + * + * @note This function is not meant to be invoked directly by the application + * code. + */ +#define pal_lld_readlatch(port) ((port)->PIO_ODSR) + +/** + * @brief Writes a bits mask on a I/O port. + * @details This function is implemented by writing the PIO_ODSR register, the + * implementation has no side effects. + * + * @param[in] port the port identifier + * @param[in] bits the bits to be written on the specified port + * + * @note This function is not meant to be invoked directly by the application + * code. + */ +#define pal_lld_writeport(port, bits) { \ + (port)->PIO_ODSR = (bits); \ +} + +/** + * @brief Sets a bits mask on a I/O port. + * @details This function is implemented by writing the PIO_SODR register, the + * implementation has no side effects. + * + * @param[in] port the port identifier + * @param[in] bits the bits to be ORed on the specified port + * + * @note This function is not meant to be invoked directly by the application + * code. + */ +#define pal_lld_setport(port, bits) { \ + (port)->PIO_SODR = (bits); \ +} + + +/** + * @brief Clears a bits mask on a I/O port. + * @details This function is implemented by writing the PIO_CODR register, the + * implementation has no side effects. + * + * @param[in] port the port identifier + * @param[in] bits the bits to be cleared on the specified port + * + * @note This function is not meant to be invoked directly by the application + * code. + */ +#define pal_lld_clearport(port, bits) { \ + (port)->PIO_CODR = (bits); \ +} + +/** + * @brief Writes a group of bits. + * @details This function is implemented by writing the PIO_OWER, PIO_ODSR and + * PIO_OWDR registers, the implementation is not atomic because the + * multiple accesses. + * + * @param[in] port the port identifier + * @param[in] mask the group mask + * @param[in] offset the group bit offset within the port + * @param[in] bits the bits to be written. Values exceeding the group width + * are masked. + * + * @note This function is not meant to be invoked directly by the application + * code. + */ +#define pal_lld_writegroup(port, mask, offset, bits) { \ + (port)->PIO_OWER = (mask) << (offset); \ + (port)->PIO_ODSR = (bits) << (offset); \ + (port)->PIO_OWDR = (mask) << (offset); \ +} + +/** + * @brief Pads group mode setup. + * @details This function programs a pads group belonging to the same port + * with the specified mode. + * + * @param[in] port the port identifier + * @param[in] mask the group mask + * @param[in] mode the mode + * + * @note This function is not meant to be invoked directly by the application + * code. + * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with high + * state. + */ +#define pal_lld_setgroupmode(port, mask, mode) \ + _pal_lld_setgroupmode(port, mask, mode) + +/** + * @brief Writes a logical state on an output pad. + * + * @param[in] port the port identifier + * @param[in] pad the pad number within the port + * @param[out] bit the logical value, the value must be @p 0 or @p 1 + * + * @note This function is not meant to be invoked directly by the application + * code. + */ +#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit) + +#ifdef __cplusplus +extern "C" { +#endif + void _pal_lld_init(const AT91SAM7XPIOConfig *config); + void _pal_lld_setgroupmode(ioportid_t port, + ioportmask_t mask, + uint_fast8_t mode); +#ifdef __cplusplus +} +#endif + +#endif /* _PAL_LLD_H_ */ + +/** @} */ diff --git a/os/io/platforms/AT91SAM7X/platform.dox b/os/io/platforms/AT91SAM7X/platform.dox new file mode 100644 index 000000000..dac6ed181 --- /dev/null +++ b/os/io/platforms/AT91SAM7X/platform.dox @@ -0,0 +1,73 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @defgroup AT91SAM7X AT91SAM7X Support + * @brief AT91SAM7X specific support. + * @details The AT91SAM7X support includes: + * - Buffered, interrupt driven, serial driver. + * - EMAC driver with MII support. + * - A demo supporting the kernel test suite. + * - A Web server demo using the uIP TCP/IP stack. + * . + * @ingroup ARM7 + */ + +/** + * @defgroup AT91SAM7X_PAL I/O Ports Support + * @brief I/O Ports peripherals support. + * @details This module supports the AT91SAM7X PIO controller. The controller + * supports the following features (see @ref PAL): + * - 32 bits wide ports. + * - Atomic set/reset functions. + * - Output latched regardless of the pad setting. + * - Direct read of input pads regardless of the pad setting. + * . + *

Supported Setup Modes

+ * - @p PAL_MODE_RESET. + * - @p PAL_MODE_UNCONNECTED. + * - @p PAL_MODE_INPUT. + * - @p PAL_MODE_INPUT_PULLUP. + * - @p PAL_MODE_OUTPUT_PUSHPULL. + * - @p PAL_MODE_OUTPUT_OPENDRAIN. + * . + * Any attempt to setup an invalid mode is ignored. + * + *

Suboptimal Behavior

+ * Some PIO features are less than optimal: + * - Pad/port toggling operations are not atomic. + * - Pad/group mode setup is not atomic. + * . + * @ingroup AT91SAM7X + */ + +/** + * @defgroup AT91SAM7X_SERIAL USART Support + * @brief USART peripherals support. + * @details The serial driver supports the AT91SAM7X USART peripherals. + * + * @ingroup AT91SAM7X + */ + +/** + * @defgroup AT91SAM7X_EMAC EMAC Support + * @brief EMAC peripheral support. + * + * @ingroup AT91SAM7X + */ diff --git a/os/io/platforms/AT91SAM7X/sam7x_emac.c b/os/io/platforms/AT91SAM7X/sam7x_emac.c new file mode 100644 index 000000000..82d7e8381 --- /dev/null +++ b/os/io/platforms/AT91SAM7X/sam7x_emac.c @@ -0,0 +1,418 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file AT91SAM7X/sam7x_emac.c + * @brief AT91SAM7X EMAC driver code. + * @addtogroup AT91SAM7X_EMAC + * @{ + */ + +#include + +#include + +#include "board.h" +#include "sam7x_emac.h" +#include "mii.h" +#include "at91lib/aic.h" + +EventSource EMACFrameTransmitted; /* A frame was transmitted. */ +EventSource EMACFrameReceived; /* A frame was received. */ + +#ifndef __DOXYGEN__ +//static int received; /* Buffered frames counter. */ +static bool_t link_up; /* Last from EMACGetLinkStatus()*/ + +static uint8_t default_mac[] = {0xAA, 0x55, 0x13, 0x37, 0x01, 0x10}; + +static BufDescriptorEntry rent[EMAC_RECEIVE_BUFFERS] __attribute__((aligned(8))); +static uint8_t rbuffers[EMAC_RECEIVE_BUFFERS * EMAC_RECEIVE_BUFFERS_SIZE] __attribute__((aligned(8))); +static BufDescriptorEntry *rxptr; + +static BufDescriptorEntry tent[EMAC_TRANSMIT_BUFFERS] __attribute__((aligned(8))); +static uint8_t tbuffers[EMAC_TRANSMIT_BUFFERS * EMAC_TRANSMIT_BUFFERS_SIZE] __attribute__((aligned(8))); +static BufDescriptorEntry *txptr; +#endif + +#define AT91C_PB15_ERXDV AT91C_PB15_ERXDV_ECRSDV +#define EMAC_PIN_MASK (AT91C_PB0_ETXCK_EREFCK | \ + AT91C_PB1_ETXEN | AT91C_PB2_ETX0 | \ + AT91C_PB3_ETX1 | AT91C_PB4_ECRS | \ + AT91C_PB5_ERX0 | AT91C_PB6_ERX1 | \ + AT91C_PB7_ERXER | AT91C_PB8_EMDC | \ + AT91C_PB9_EMDIO | AT91C_PB10_ETX2 | \ + AT91C_PB11_ETX3 | AT91C_PB12_ETXER | \ + AT91C_PB13_ERX2 | AT91C_PB14_ERX3 | \ + AT91C_PB15_ERXDV | AT91C_PB16_ECOL | \ + AT91C_PB17_ERXCK) + +#define PHY_LATCHED_PINS (AT91C_PB4_ECRS | AT91C_PB5_ERX0 | AT91C_PB6_ERX1 | \ + AT91C_PB7_ERXER | AT91C_PB13_ERX2 | AT91C_PB14_ERX3 | \ + AT91C_PB15_ERXDV | AT91C_PB16_ECOL | PIOB_PHY_IRQ_MASK) + +/* + * PHY utilities. + */ +static uint32_t phy_get(uint8_t regno) { + + AT91C_BASE_EMAC->EMAC_MAN = (1 << 30) | // SOF = 01 + (2 << 28) | // RW = 10 + (PHY_ADDRESS << 23) | + (regno << 18) | + (2 << 16); // CODE = 10 + while (!( AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE)) + ; + return AT91C_BASE_EMAC->EMAC_MAN & 0xFFFF; +} + +/*static void phy_put(uint8_t regno, uint32_t val) { + + AT91C_BASE_EMAC->EMAC_MAN = (1 << 30) | // SOF = 01 + (1 << 28) | // RW = 01 + (PHY_ADDRESS << 23) | + (regno << 18) | + (2 << 16) | // CODE = 10 + val; + while (!( AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE)) + ; +}*/ + +#define RSR_BITS (AT91C_EMAC_BNA | AT91C_EMAC_REC | AT91C_EMAC_OVR) +#define TSR_BITS (AT91C_EMAC_UBR | AT91C_EMAC_COL | AT91C_EMAC_RLES | \ + AT91C_EMAC_BEX | AT91C_EMAC_COMP | AT91C_EMAC_UND) + +__attribute__((noinline)) +static void ServeInterrupt(void) { + uint32_t isr, rsr, tsr; + + /* Fix for the EMAC errata */ + isr = AT91C_BASE_EMAC->EMAC_ISR; + rsr = AT91C_BASE_EMAC->EMAC_RSR; + tsr = AT91C_BASE_EMAC->EMAC_TSR; + + if ((isr & AT91C_EMAC_RCOMP) || (rsr & RSR_BITS)) { + if (rsr & AT91C_EMAC_REC) { +// received++; + chSysLockFromIsr(); + chEvtBroadcastI(&EMACFrameReceived); + chSysUnlockFromIsr(); + } + AT91C_BASE_EMAC->EMAC_RSR = RSR_BITS; + } + + if ((isr & AT91C_EMAC_TCOMP) || (tsr & TSR_BITS)) { + if (tsr & AT91C_EMAC_COMP) { + chSysLockFromIsr(); + chEvtBroadcastI(&EMACFrameTransmitted); + chSysUnlockFromIsr(); + } + AT91C_BASE_EMAC->EMAC_TSR = TSR_BITS; + } + AT91C_BASE_AIC->AIC_EOICR = 0; +} + +CH_IRQ_HANDLER(EMACIrqHandler) { + + CH_IRQ_PROLOGUE(); + + ServeInterrupt(); + + CH_IRQ_EPILOGUE(); +} + +/* + * EMAC subsystem initialization. + */ +void emac_init(int prio) { + int i; + + /* + * Buffers initialization. + */ +// received = 0; + for (i = 0; i < EMAC_RECEIVE_BUFFERS; i++) { + rent[i].w1 = (uint32_t)&rbuffers[i * EMAC_RECEIVE_BUFFERS_SIZE]; + rent[i].w2 = 0; + } + rent[EMAC_RECEIVE_BUFFERS - 1].w1 |= W1_R_WRAP; + rxptr = rent; + for (i = 0; i < EMAC_TRANSMIT_BUFFERS; i++) { + tent[i].w1 = (uint32_t)&tbuffers[i * EMAC_TRANSMIT_BUFFERS_SIZE]; + tent[i].w2 = EMAC_TRANSMIT_BUFFERS_SIZE | W2_T_USED; + } + tent[EMAC_TRANSMIT_BUFFERS - 1].w2 |= W2_T_WRAP; + txptr = tent; + + /* + * Disables the pullups on all the pins that are latched on reset by the PHY. + * The status latched into the PHY is: + * PHYADDR = 00001 + * PCS_LPBK = 0 (disabled) + * ISOLATE = 0 (disabled) + * RMIISEL = 0 (MII mode) + * RMIIBTB = 0 (BTB mode disabled) + * SPEED = 1 (100mbps) + * DUPLEX = 1 (full duplex) + * ANEG_EN = 1 (auto negotiation enabled) + */ + AT91C_BASE_PIOB->PIO_PPUDR = PHY_LATCHED_PINS; + + /* + * PHY power control. + */ + AT91C_BASE_PIOB->PIO_OER = PIOB_PHY_PD_MASK; // Becomes an output. + AT91C_BASE_PIOB->PIO_PPUDR = PIOB_PHY_PD_MASK; // Default pullup disabled. + AT91C_BASE_PIOB->PIO_SODR = PIOB_PHY_PD_MASK; // Output to high level. + + /* + * PHY reset by pulsing the NRST pin. + */ + AT91C_BASE_RSTC->RSTC_RMR = 0xA5000100; + AT91C_BASE_RSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST; + while (!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL)) + ; + + /* + * EMAC pins setup and clock enable. Note, PB18 is not included because it is + * used as #PD control and not as EF100. + */ + AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_EMAC; + AT91C_BASE_PIOB->PIO_ASR = EMAC_PIN_MASK; + AT91C_BASE_PIOB->PIO_PDR = EMAC_PIN_MASK; + AT91C_BASE_PIOB->PIO_PPUDR = EMAC_PIN_MASK; + + /* + * EMAC setup. + */ + AT91C_BASE_EMAC->EMAC_NCR = 0; // Initial setting. + AT91C_BASE_EMAC->EMAC_NCFGR = 2 << 10; // MDC-CLK = MCK / 32 + AT91C_BASE_EMAC->EMAC_USRIO = AT91C_EMAC_CLKEN; // Enable EMAC in MII mode + AT91C_BASE_EMAC->EMAC_RBQP = (AT91_REG)rent; // RX buffers list + AT91C_BASE_EMAC->EMAC_TBQP = (AT91_REG)tent; // TX buffers list + AT91C_BASE_EMAC->EMAC_RSR = AT91C_EMAC_OVR | + AT91C_EMAC_REC | + AT91C_EMAC_BNA; // Clears RSR + AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_DRFCS; // Initial NCFGR settings + AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TE | + AT91C_EMAC_RE | + AT91C_EMAC_CLRSTAT; // Initial NCR settings + EMACSetAddress(default_mac); + + /* + * PHY detection and settings. + */ + AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE; + if ((phy_get(MII_PHYSID1) != (MII_MICREL_ID >> 16)) || + ((phy_get(MII_PHYSID2) & 0xFFF0) != (MII_MICREL_ID & 0xFFF0))) + chSysHalt(); + + /* + * Waits for auto-negotiation to end and then detects the link status. + */ + AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; + + /* + * Interrupt setup. + */ + AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP; + AIC_ConfigureIT(AT91C_ID_EMAC, + AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | prio, + EMACIrqHandler); + AIC_EnableIT(AT91C_ID_EMAC); + + /* + * Event sources setup. + */ + chEvtInit(&EMACFrameTransmitted); + chEvtInit(&EMACFrameReceived); +} + +/* + * Set the MAC address. + */ +void EMACSetAddress(const uint8_t *eaddr) { + + AT91C_BASE_EMAC->EMAC_SA1L = (AT91_REG)((eaddr[3] << 24) | (eaddr[2] << 16) | + (eaddr[1] << 8) | eaddr[0]); + AT91C_BASE_EMAC->EMAC_SA1H = (AT91_REG)((eaddr[5] << 8) | eaddr[4]); +} + +/* + * Returns TRUE if the link is active. To be invoked at regular intervals in + * order to monitor the link. + * @note It is not thread-safe. + */ +bool_t EMACGetLinkStatus(void) { + uint32_t ncfgr, bmsr, bmcr, lpa; + + AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE; + (void)phy_get(MII_BMSR); + bmsr = phy_get(MII_BMSR); + if (!(bmsr & BMSR_LSTATUS)) { + AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; + return link_up = FALSE; + } + + ncfgr = AT91C_BASE_EMAC->EMAC_NCFGR & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); + bmcr = phy_get(MII_BMCR); + if (bmcr & BMCR_ANENABLE) { + lpa = phy_get(MII_LPA); + if (lpa & (LPA_100HALF | LPA_100FULL | LPA_100BASE4)) + ncfgr |= AT91C_EMAC_SPD; + if (lpa & (LPA_10FULL | LPA_100FULL)) + ncfgr |= AT91C_EMAC_FD; + } + else { + if (bmcr & BMCR_SPEED100) + ncfgr |= AT91C_EMAC_SPD; + if (bmcr & BMCR_FULLDPLX) + ncfgr |= AT91C_EMAC_FD; + } + AT91C_BASE_EMAC->EMAC_NCFGR = ncfgr; + AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; + return link_up = TRUE; +} + +/* + * Allocates and locks a buffer for a transmission operation. + */ +BufDescriptorEntry *EMACGetTransmitBuffer(void) { + BufDescriptorEntry *cptr; + + if (!link_up) + return NULL; + + chSysLock(); + cptr = txptr; + if (!(cptr->w2 & W2_T_USED) || + (cptr->w2 & W2_T_LOCKED)) { + chSysUnlock(); + return FALSE; + } + cptr->w2 |= W2_T_LOCKED; /* Locks the buffer while copying.*/ + if (++txptr >= &tent[EMAC_TRANSMIT_BUFFERS]) + txptr = tent; + chSysUnlock(); + return cptr; +} + +/* + * Transmits a previously allocated buffer and then releases it. + */ +void EMACTransmit(BufDescriptorEntry *cptr, size_t size) { + + chDbgAssert(size <= EMAC_TRANSMIT_BUFFERS_SIZE, + "EMACTransmit(), #1", + "unexpected size"); + + chSysLock(); + if (cptr < &tent[EMAC_TRANSMIT_BUFFERS - 1]) + cptr->w2 = size | W2_T_LAST_BUFFER; + else + cptr->w2 = size | W2_T_LAST_BUFFER | W2_T_WRAP; + AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART; + chSysUnlock(); +} + +/* + * Reads a buffered frame. + * Returns TRUE if a frame was present and read else FALSE. + * @note It is not thread-safe. + */ +bool_t EMACReceive(uint8_t *buf, size_t *sizep) { + unsigned n; + size_t size; + uint8_t *p; + bool_t overflow, found; + +// chSysLock(); +// if (received <= 0) { +// chSysUnlock(); +// return FALSE; +// } +// received--; +// chSysUnlock(); + + n = EMAC_RECEIVE_BUFFERS; + + /* + * Skips unused buffers, if any. + */ +skip: + while (n && !(rxptr->w1 & W1_R_OWNERSHIP)) { + if (++rxptr >= &rent[EMAC_RECEIVE_BUFFERS]) + rxptr = rent; + n--; + } + + /* + * Skips fragments, if any. + */ + while (n && (rxptr->w1 & W1_R_OWNERSHIP) && !(rxptr->w2 & W2_R_FRAME_START)) { + rxptr->w1 &= ~W1_R_OWNERSHIP; + if (++rxptr >= &rent[EMAC_RECEIVE_BUFFERS]) + rxptr = rent; + n--; + } + +restart: + p = buf; + size = 0; + found = overflow = FALSE; + while (n && !found) { + size_t segsize; + + if (!(rxptr->w1 & W1_R_OWNERSHIP)) + goto skip; /* Empty buffer for some reason... */ + + if (size && (rxptr->w2 & W2_R_FRAME_START)) + goto restart; /* Another start buffer for some reason... */ + + if (rxptr->w2 & W2_R_FRAME_END) { + segsize = (rxptr->w2 & W2_T_LENGTH_MASK) - size; + if (((rxptr->w2 & W2_T_LENGTH_MASK) > *sizep) || + (segsize > EMAC_RECEIVE_BUFFERS_SIZE)) + overflow = TRUE; + found = TRUE; + } + else { + segsize = EMAC_RECEIVE_BUFFERS_SIZE; + if (size + segsize > *sizep) + overflow = TRUE; + } + + if (!overflow) { + chDbgAssert(segsize <= 128, "EMACReceive(), #1", ""); + memcpy(p, (void *)(rxptr->w1 & W1_R_ADDRESS_MASK), segsize); + p += segsize; + size += segsize; + } + + rxptr->w1 &= ~W1_R_OWNERSHIP; + if (++rxptr >= &rent[EMAC_RECEIVE_BUFFERS]) + rxptr = rent; + n--; + } + + *sizep = size; + return found && !overflow; +} + +/** @} */ diff --git a/os/io/platforms/AT91SAM7X/sam7x_emac.h b/os/io/platforms/AT91SAM7X/sam7x_emac.h new file mode 100644 index 000000000..de81fe4c6 --- /dev/null +++ b/os/io/platforms/AT91SAM7X/sam7x_emac.h @@ -0,0 +1,93 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file AT91SAM7X/sam7x_emac.h + * @brief AT91SAM7X EMAC driver macros and structures. + * @addtogroup AT91SAM7X_EMAC + * @{ + */ + +#ifndef _SAM7X_EMAC_H_ +#define _SAM7X_EMAC_H_ + +#define PHY_ADDRESS 1 + +#define EMAC_RECEIVE_BUFFERS 24 +#define EMAC_RECEIVE_BUFFERS_SIZE 128 +#define EMAC_TRANSMIT_BUFFERS 2 +#define EMAC_TRANSMIT_BUFFERS_SIZE 1518 + +typedef struct { + uint32_t w1; + uint32_t w2; +} BufDescriptorEntry; + +#define W1_R_OWNERSHIP 0x00000001 +#define W1_R_WRAP 0x00000002 +#define W1_R_ADDRESS_MASK 0xFFFFFFFC + +#define W2_R_LENGTH_MASK 0x00000FFF +#define W2_R_FRAME_START 0x00004000 +#define W2_R_FRAME_END 0x00008000 +#define W2_R_CFI 0x00010000 +#define W2_R_VLAN_PRIO_MASK 0x000E0000 +#define W2_R_PRIO_TAG_DETECTED 0x00100000 +#define W2_R_VLAN_TAG_DETECTED 0x00200000 +#define W2_R_TYPE_ID_MATCH 0x00400000 +#define W2_R_ADDR4_MATCH 0x00800000 +#define W2_R_ADDR3_MATCH 0x01000000 +#define W2_R_ADDR2_MATCH 0x02000000 +#define W2_R_ADDR1_MATCH 0x04000000 +#define W2_R_RFU1 0x08000000 +#define W2_R_ADDR_EXT_MATCH 0x10000000 +#define W2_R_UNICAST_MATCH 0x20000000 +#define W2_R_MULTICAST_MATCH 0x40000000 +#define W2_R_BROADCAST_DETECTED 0x80000000 + +#define W2_T_LENGTH_MASK 0x000007FF +#define W2_T_LOCKED 0x00000800 /* Not an EMAC flag, used by the driver */ +#define W2_T_RFU1 0x00003000 +#define W2_T_LAST_BUFFER 0x00008000 +#define W2_T_NO_CRC 0x00010000 +#define W2_T_RFU2 0x07FE0000 +#define W2_T_BUFFERS_EXHAUSTED 0x08000000 +#define W2_T_TRANSMIT_UNDERRUN 0x10000000 +#define W2_T_RETRY_LIMIT_EXC 0x20000000 +#define W2_T_WRAP 0x40000000 +#define W2_T_USED 0x80000000 + +#ifdef __cplusplus +extern "C" { +#endif + void emac_init(int prio); + void EMACSetAddress(const uint8_t *eaddr); + bool_t EMACGetLinkStatus(void); + BufDescriptorEntry *EMACGetTransmitBuffer(void); + void EMACTransmit(BufDescriptorEntry *cptr, size_t size); + bool_t EMACReceive(uint8_t *buf, size_t *sizep); +#ifdef __cplusplus +} +#endif + +extern EventSource EMACFrameTransmitted, EMACFrameReceived; + +#endif /* _SAM7X_EMAC_H_ */ + +/** @} */ diff --git a/os/ports/GCC/ARM7/AT91SAM7X/mii.h b/os/ports/GCC/ARM7/AT91SAM7X/mii.h deleted file mode 100644 index 4ec25667a..000000000 --- a/os/ports/GCC/ARM7/AT91SAM7X/mii.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/* - * Parts of this file are borrowed by the Linux include file linux/mii.h: - * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com) - */ - -#ifndef _MII_H_ -#define _MII_H_ - -/* Generic MII registers. */ -#define MII_BMCR 0x00 /* Basic mode control register */ -#define MII_BMSR 0x01 /* Basic mode status register */ -#define MII_PHYSID1 0x02 /* PHYS ID 1 */ -#define MII_PHYSID2 0x03 /* PHYS ID 2 */ -#define MII_ADVERTISE 0x04 /* Advertisement control reg */ -#define MII_LPA 0x05 /* Link partner ability reg */ -#define MII_EXPANSION 0x06 /* Expansion register */ -#define MII_CTRL1000 0x09 /* 1000BASE-T control */ -#define MII_STAT1000 0x0a /* 1000BASE-T status */ -#define MII_ESTATUS 0x0f /* Extended Status */ -#define MII_DCOUNTER 0x12 /* Disconnect counter */ -#define MII_FCSCOUNTER 0x13 /* False carrier counter */ -#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ -#define MII_RERRCOUNTER 0x15 /* Receive error counter */ -#define MII_SREVISION 0x16 /* Silicon revision */ -#define MII_RESV1 0x17 /* Reserved... */ -#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ -#define MII_PHYADDR 0x19 /* PHY address */ -#define MII_RESV2 0x1a /* Reserved... */ -#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */ -#define MII_NCONFIG 0x1c /* Network interface config */ - -/* Basic mode control register. */ -#define BMCR_RESV 0x003f /* Unused... */ -#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ -#define BMCR_CTST 0x0080 /* Collision test */ -#define BMCR_FULLDPLX 0x0100 /* Full duplex */ -#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ -#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ -#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ -#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ -#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ -#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ -#define BMCR_RESET 0x8000 /* Reset the DP83840 */ - -/* Basic mode status register. */ -#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ -#define BMSR_JCD 0x0002 /* Jabber detected */ -#define BMSR_LSTATUS 0x0004 /* Link status */ -#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ -#define BMSR_RFAULT 0x0010 /* Remote fault detected */ -#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ -#define BMSR_RESV 0x00c0 /* Unused... */ -#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ -#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */ -#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */ -#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ -#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ -#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ -#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ -#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ - -/* Advertisement control register. */ -#define ADVERTISE_SLCT 0x001f /* Selector bits */ -#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ -#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ -#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */ -#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ -#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */ -#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ -#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */ -#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ -#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */ -#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ -#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */ -#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */ -#define ADVERTISE_RESV 0x1000 /* Unused... */ -#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ -#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ -#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ - -#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \ - ADVERTISE_CSMA) -#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \ - ADVERTISE_100HALF | ADVERTISE_100FULL) - -/* Link partner ability register. */ -#define LPA_SLCT 0x001f /* Same as advertise selector */ -#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ -#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */ -#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ -#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */ -#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ -#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */ -#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ -#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/ -#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */ -#define LPA_PAUSE_CAP 0x0400 /* Can pause */ -#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */ -#define LPA_RESV 0x1000 /* Unused... */ -#define LPA_RFAULT 0x2000 /* Link partner faulted */ -#define LPA_LPACK 0x4000 /* Link partner acked us */ -#define LPA_NPAGE 0x8000 /* Next page bit */ - -#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL) -#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) - -/* Expansion register for auto-negotiation. */ -#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */ -#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */ -#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */ -#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */ -#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */ -#define EXPANSION_RESV 0xffe0 /* Unused... */ - -#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */ -#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */ - -/* N-way test register. */ -#define NWAYTEST_RESV1 0x00ff /* Unused... */ -#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */ -#define NWAYTEST_RESV2 0xfe00 /* Unused... */ - -/* 1000BASE-T Control register */ -#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ -#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ - -/* 1000BASE-T Status register */ -#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */ -#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */ -#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */ -#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */ - -#define MII_DM9161_ID 0x0181b8a0 -#define MII_AM79C875_ID 0x00225540 -#define MII_MICREL_ID 0x00221610 - -#endif /* _MII_H_ */ diff --git a/os/ports/GCC/ARM7/AT91SAM7X/pal_lld.c b/os/ports/GCC/ARM7/AT91SAM7X/pal_lld.c deleted file mode 100644 index 6c8b26cda..000000000 --- a/os/ports/GCC/ARM7/AT91SAM7X/pal_lld.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file os/ports/GCC/ARM7/AT91SAM7X/pal_lld.c - * @brief AT91SAM7X PIO low level driver code - * @addtogroup AT91SAM7X_PAL - * @{ - */ - -#include -#include - -/** - * @brief AT91SAM7X I/O ports configuration. - * @details PIO registers initialization. - * - * @param[in] config the AT91SAM7X ports configuration - */ -void _pal_lld_init(const AT91SAM7XPIOConfig *config) { - - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOA) | (1 << AT91C_ID_PIOB); - - /* - * PIOA setup. - */ - AT91C_BASE_PIOA->PIO_OER = config->P0Data.pusr; /* Pull-up as spec.*/ - AT91C_BASE_PIOA->PIO_ODR = ~config->P0Data.pusr; - AT91C_BASE_PIOA->PIO_PER = 0xFFFFFFFF; /* PIO enabled.*/ - AT91C_BASE_PIOA->PIO_ODSR = config->P0Data.odsr; /* Data as specified.*/ - AT91C_BASE_PIOA->PIO_OER = config->P0Data.osr; /* Dir. as specified.*/ - AT91C_BASE_PIOA->PIO_ODR = ~config->P0Data.osr; - AT91C_BASE_PIOA->PIO_IFDR = 0xFFFFFFFF; /* Filter disabled.*/ - AT91C_BASE_PIOA->PIO_IDR = 0xFFFFFFFF; /* Int. disabled.*/ - AT91C_BASE_PIOA->PIO_MDDR = 0xFFFFFFFF; /* Push Pull drive.*/ - AT91C_BASE_PIOA->PIO_ASR = 0xFFFFFFFF; /* Peripheral A.*/ - AT91C_BASE_PIOA->PIO_OWER = 0xFFFFFFFF; /* Write enabled.*/ - - /* - * PIOB setup. - */ - AT91C_BASE_PIOB->PIO_OER = config->P0Data.pusr; /* Pull-up as spec.*/ - AT91C_BASE_PIOB->PIO_ODR = ~config->P0Data.pusr; - AT91C_BASE_PIOB->PIO_PER = 0xFFFFFFFF; /* PIO enabled.*/ - AT91C_BASE_PIOB->PIO_ODSR = config->P1Data.odsr; /* Data as specified.*/ - AT91C_BASE_PIOB->PIO_OER = config->P1Data.osr; /* Dir. as specified.*/ - AT91C_BASE_PIOB->PIO_ODR = ~config->P1Data.osr; - AT91C_BASE_PIOB->PIO_IFDR = 0xFFFFFFFF; /* Filter disabled.*/ - AT91C_BASE_PIOB->PIO_IDR = 0xFFFFFFFF; /* Int. disabled.*/ - AT91C_BASE_PIOB->PIO_MDDR = 0xFFFFFFFF; /* Push Pull drive.*/ - AT91C_BASE_PIOB->PIO_ASR = 0xFFFFFFFF; /* Peripheral A.*/ - AT91C_BASE_PIOB->PIO_OWER = 0xFFFFFFFF; /* Write enabled.*/ -} - -/** - * @brief Pads mode setup. - * @details This function programs a pads group belonging to the same port - * with the specified mode. - * - * @param[in] port the port identifier - * @param[in] mask the group mask - * @param[in] mode the mode - * - * @note This function is not meant to be invoked directly by the application - * code. - * @note @p PAL_MODE_RESET is implemented as input with pull-up. - * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with high - * state. - * @note @p PAL_MODE_OUTPUT_OPENDRAIN also enables the pull-up resistor. - */ -void _pal_lld_setgroupmode(ioportid_t port, - ioportmask_t mask, - uint_fast8_t mode) { - - switch (mode & PAL_MODE_MASK) { - case PAL_MODE_RESET: - case PAL_MODE_INPUT_PULLUP: - port->PIO_PPUER = mask; - port->PIO_ODR = mask; - break; - case PAL_MODE_INPUT: - port->PIO_PPUDR = mask; - port->PIO_ODR = mask; - break; - case PAL_MODE_UNCONNECTED: - port->PIO_SODR = mask; - /* Falls in */ - case PAL_MODE_OUTPUT_PUSHPULL: - port->PIO_PPUDR = mask; - port->PIO_OER = mask; - port->PIO_MDDR = mask; - break; - case PAL_MODE_OUTPUT_OPENDRAIN: - port->PIO_PPUER = mask; - port->PIO_OER = mask; - port->PIO_MDER = mask; - } -} - -/** @} */ diff --git a/os/ports/GCC/ARM7/AT91SAM7X/pal_lld.h b/os/ports/GCC/ARM7/AT91SAM7X/pal_lld.h deleted file mode 100644 index 1f50b5734..000000000 --- a/os/ports/GCC/ARM7/AT91SAM7X/pal_lld.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file os/ports/GCC/ARM7/AT91SAM7X/pal_lld.h - * @brief AT91SAM7X PIO low level driver header - * @addtogroup AT91SAM7X_PAL - * @{ - */ - -#ifndef _PAL_LLD_H_ -#define _PAL_LLD_H_ - -#include "at91lib/AT91SAM7X256.h" - -/*===========================================================================*/ -/* Unsupported modes and specific modes */ -/*===========================================================================*/ - -#undef PAL_MODE_INPUT_PULLDOWN - -/*===========================================================================*/ -/* I/O Ports Types and constants. */ -/*===========================================================================*/ - -/** - * @brief PIO port setup info. - */ -typedef struct { - /** Initial value for ODSR register (data).*/ - uint32_t odsr; - /** Initial value for OSR register (direction).*/ - uint32_t osr; - /** Initial value for PUSR register (Pull-ups).*/ - uint32_t pusr; -} at91sam7x_pio_setup_t; - -/** - * @brief AT91SAM7X PIO static initializer. - * @details An instance of this structure must be passed to @p palInit() at - * system startup time in order to initialized the digital I/O - * subsystem. This represents only the initial setup, specific pads - * or whole ports can be reprogrammed at later time. - */ -typedef struct { - /** @brief Port 0 setup data.*/ - at91sam7x_pio_setup_t P0Data; - /** @brief Port 1 setup data.*/ - at91sam7x_pio_setup_t P1Data; -} AT91SAM7XPIOConfig; - -/** - * @brief Width, in bits, of an I/O port. - */ -#define PAL_IOPORTS_WIDTH 32 - -/** - * @brief Digital I/O port sized unsigned type. - */ -typedef uint32_t ioportmask_t; - -/** - * @brief Port Identifier. - * @details This type can be a scalar or some kind of pointer, do not make - * any assumption about it, use the provided macros when populating - * variables of this type. - */ -typedef AT91PS_PIO ioportid_t; - -/*===========================================================================*/ -/* I/O Ports Identifiers. */ -/*===========================================================================*/ - -/** - * @brief PIO port A identifier. - */ -#define IOPORT_A AT91C_BASE_PIOA - -/** - * @brief PIO port B identifier. - */ -#define IOPORT_B AT91C_BASE_PIOB - -/*===========================================================================*/ -/* Implementation, some of the following macros could be implemented as */ -/* functions, if so please put them in a file named pal_lld.c. */ -/*===========================================================================*/ - -/** - * @brief Low level PAL subsystem initialization. - */ -#define pal_lld_init(config) _pal_lld_init(config) - -/** - * @brief Reads the physical I/O port states. - * @details This function is implemented by reading the PIO_PDSR register, the - * implementation has no side effects. - * - * @param[in] port the port identifier - * @return The port bits. - * - * @note This function is not meant to be invoked directly by the application - * code. - */ -#define pal_lld_readport(port) ((port)->PIO_PDSR) - -/** - * @brief Reads the output latch. - * @details This function is implemented by reading the PIO_ODSR register, the - * implementation has no side effects. - * - * @param[in] port the port identifier - * @return The latched logical states. - * - * @note This function is not meant to be invoked directly by the application - * code. - */ -#define pal_lld_readlatch(port) ((port)->PIO_ODSR) - -/** - * @brief Writes a bits mask on a I/O port. - * @details This function is implemented by writing the PIO_ODSR register, the - * implementation has no side effects. - * - * @param[in] port the port identifier - * @param[in] bits the bits to be written on the specified port - * - * @note This function is not meant to be invoked directly by the application - * code. - */ -#define pal_lld_writeport(port, bits) { \ - (port)->PIO_ODSR = (bits); \ -} - -/** - * @brief Sets a bits mask on a I/O port. - * @details This function is implemented by writing the PIO_SODR register, the - * implementation has no side effects. - * - * @param[in] port the port identifier - * @param[in] bits the bits to be ORed on the specified port - * - * @note This function is not meant to be invoked directly by the application - * code. - */ -#define pal_lld_setport(port, bits) { \ - (port)->PIO_SODR = (bits); \ -} - - -/** - * @brief Clears a bits mask on a I/O port. - * @details This function is implemented by writing the PIO_CODR register, the - * implementation has no side effects. - * - * @param[in] port the port identifier - * @param[in] bits the bits to be cleared on the specified port - * - * @note This function is not meant to be invoked directly by the application - * code. - */ -#define pal_lld_clearport(port, bits) { \ - (port)->PIO_CODR = (bits); \ -} - -/** - * @brief Writes a group of bits. - * @details This function is implemented by writing the PIO_OWER, PIO_ODSR and - * PIO_OWDR registers, the implementation is not atomic because the - * multiple accesses. - * - * @param[in] port the port identifier - * @param[in] mask the group mask - * @param[in] offset the group bit offset within the port - * @param[in] bits the bits to be written. Values exceeding the group width - * are masked. - * - * @note This function is not meant to be invoked directly by the application - * code. - */ -#define pal_lld_writegroup(port, mask, offset, bits) { \ - (port)->PIO_OWER = (mask) << (offset); \ - (port)->PIO_ODSR = (bits) << (offset); \ - (port)->PIO_OWDR = (mask) << (offset); \ -} - -/** - * @brief Pads group mode setup. - * @details This function programs a pads group belonging to the same port - * with the specified mode. - * - * @param[in] port the port identifier - * @param[in] mask the group mask - * @param[in] mode the mode - * - * @note This function is not meant to be invoked directly by the application - * code. - * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with high - * state. - */ -#define pal_lld_setgroupmode(port, mask, mode) \ - _pal_lld_setgroupmode(port, mask, mode) - -/** - * @brief Writes a logical state on an output pad. - * - * @param[in] port the port identifier - * @param[in] pad the pad number within the port - * @param[out] bit the logical value, the value must be @p 0 or @p 1 - * - * @note This function is not meant to be invoked directly by the application - * code. - */ -#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit) - -#ifdef __cplusplus -extern "C" { -#endif - void _pal_lld_init(const AT91SAM7XPIOConfig *config); - void _pal_lld_setgroupmode(ioportid_t port, - ioportmask_t mask, - uint_fast8_t mode); -#ifdef __cplusplus -} -#endif - -#endif /* _PAL_LLD_H_ */ - -/** @} */ diff --git a/os/ports/GCC/ARM7/AT91SAM7X/port.dox b/os/ports/GCC/ARM7/AT91SAM7X/port.dox deleted file mode 100644 index dac6ed181..000000000 --- a/os/ports/GCC/ARM7/AT91SAM7X/port.dox +++ /dev/null @@ -1,73 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @defgroup AT91SAM7X AT91SAM7X Support - * @brief AT91SAM7X specific support. - * @details The AT91SAM7X support includes: - * - Buffered, interrupt driven, serial driver. - * - EMAC driver with MII support. - * - A demo supporting the kernel test suite. - * - A Web server demo using the uIP TCP/IP stack. - * . - * @ingroup ARM7 - */ - -/** - * @defgroup AT91SAM7X_PAL I/O Ports Support - * @brief I/O Ports peripherals support. - * @details This module supports the AT91SAM7X PIO controller. The controller - * supports the following features (see @ref PAL): - * - 32 bits wide ports. - * - Atomic set/reset functions. - * - Output latched regardless of the pad setting. - * - Direct read of input pads regardless of the pad setting. - * . - *

Supported Setup Modes

- * - @p PAL_MODE_RESET. - * - @p PAL_MODE_UNCONNECTED. - * - @p PAL_MODE_INPUT. - * - @p PAL_MODE_INPUT_PULLUP. - * - @p PAL_MODE_OUTPUT_PUSHPULL. - * - @p PAL_MODE_OUTPUT_OPENDRAIN. - * . - * Any attempt to setup an invalid mode is ignored. - * - *

Suboptimal Behavior

- * Some PIO features are less than optimal: - * - Pad/port toggling operations are not atomic. - * - Pad/group mode setup is not atomic. - * . - * @ingroup AT91SAM7X - */ - -/** - * @defgroup AT91SAM7X_SERIAL USART Support - * @brief USART peripherals support. - * @details The serial driver supports the AT91SAM7X USART peripherals. - * - * @ingroup AT91SAM7X - */ - -/** - * @defgroup AT91SAM7X_EMAC EMAC Support - * @brief EMAC peripheral support. - * - * @ingroup AT91SAM7X - */ diff --git a/os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.c b/os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.c deleted file mode 100644 index 82d7e8381..000000000 --- a/os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file AT91SAM7X/sam7x_emac.c - * @brief AT91SAM7X EMAC driver code. - * @addtogroup AT91SAM7X_EMAC - * @{ - */ - -#include - -#include - -#include "board.h" -#include "sam7x_emac.h" -#include "mii.h" -#include "at91lib/aic.h" - -EventSource EMACFrameTransmitted; /* A frame was transmitted. */ -EventSource EMACFrameReceived; /* A frame was received. */ - -#ifndef __DOXYGEN__ -//static int received; /* Buffered frames counter. */ -static bool_t link_up; /* Last from EMACGetLinkStatus()*/ - -static uint8_t default_mac[] = {0xAA, 0x55, 0x13, 0x37, 0x01, 0x10}; - -static BufDescriptorEntry rent[EMAC_RECEIVE_BUFFERS] __attribute__((aligned(8))); -static uint8_t rbuffers[EMAC_RECEIVE_BUFFERS * EMAC_RECEIVE_BUFFERS_SIZE] __attribute__((aligned(8))); -static BufDescriptorEntry *rxptr; - -static BufDescriptorEntry tent[EMAC_TRANSMIT_BUFFERS] __attribute__((aligned(8))); -static uint8_t tbuffers[EMAC_TRANSMIT_BUFFERS * EMAC_TRANSMIT_BUFFERS_SIZE] __attribute__((aligned(8))); -static BufDescriptorEntry *txptr; -#endif - -#define AT91C_PB15_ERXDV AT91C_PB15_ERXDV_ECRSDV -#define EMAC_PIN_MASK (AT91C_PB0_ETXCK_EREFCK | \ - AT91C_PB1_ETXEN | AT91C_PB2_ETX0 | \ - AT91C_PB3_ETX1 | AT91C_PB4_ECRS | \ - AT91C_PB5_ERX0 | AT91C_PB6_ERX1 | \ - AT91C_PB7_ERXER | AT91C_PB8_EMDC | \ - AT91C_PB9_EMDIO | AT91C_PB10_ETX2 | \ - AT91C_PB11_ETX3 | AT91C_PB12_ETXER | \ - AT91C_PB13_ERX2 | AT91C_PB14_ERX3 | \ - AT91C_PB15_ERXDV | AT91C_PB16_ECOL | \ - AT91C_PB17_ERXCK) - -#define PHY_LATCHED_PINS (AT91C_PB4_ECRS | AT91C_PB5_ERX0 | AT91C_PB6_ERX1 | \ - AT91C_PB7_ERXER | AT91C_PB13_ERX2 | AT91C_PB14_ERX3 | \ - AT91C_PB15_ERXDV | AT91C_PB16_ECOL | PIOB_PHY_IRQ_MASK) - -/* - * PHY utilities. - */ -static uint32_t phy_get(uint8_t regno) { - - AT91C_BASE_EMAC->EMAC_MAN = (1 << 30) | // SOF = 01 - (2 << 28) | // RW = 10 - (PHY_ADDRESS << 23) | - (regno << 18) | - (2 << 16); // CODE = 10 - while (!( AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE)) - ; - return AT91C_BASE_EMAC->EMAC_MAN & 0xFFFF; -} - -/*static void phy_put(uint8_t regno, uint32_t val) { - - AT91C_BASE_EMAC->EMAC_MAN = (1 << 30) | // SOF = 01 - (1 << 28) | // RW = 01 - (PHY_ADDRESS << 23) | - (regno << 18) | - (2 << 16) | // CODE = 10 - val; - while (!( AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE)) - ; -}*/ - -#define RSR_BITS (AT91C_EMAC_BNA | AT91C_EMAC_REC | AT91C_EMAC_OVR) -#define TSR_BITS (AT91C_EMAC_UBR | AT91C_EMAC_COL | AT91C_EMAC_RLES | \ - AT91C_EMAC_BEX | AT91C_EMAC_COMP | AT91C_EMAC_UND) - -__attribute__((noinline)) -static void ServeInterrupt(void) { - uint32_t isr, rsr, tsr; - - /* Fix for the EMAC errata */ - isr = AT91C_BASE_EMAC->EMAC_ISR; - rsr = AT91C_BASE_EMAC->EMAC_RSR; - tsr = AT91C_BASE_EMAC->EMAC_TSR; - - if ((isr & AT91C_EMAC_RCOMP) || (rsr & RSR_BITS)) { - if (rsr & AT91C_EMAC_REC) { -// received++; - chSysLockFromIsr(); - chEvtBroadcastI(&EMACFrameReceived); - chSysUnlockFromIsr(); - } - AT91C_BASE_EMAC->EMAC_RSR = RSR_BITS; - } - - if ((isr & AT91C_EMAC_TCOMP) || (tsr & TSR_BITS)) { - if (tsr & AT91C_EMAC_COMP) { - chSysLockFromIsr(); - chEvtBroadcastI(&EMACFrameTransmitted); - chSysUnlockFromIsr(); - } - AT91C_BASE_EMAC->EMAC_TSR = TSR_BITS; - } - AT91C_BASE_AIC->AIC_EOICR = 0; -} - -CH_IRQ_HANDLER(EMACIrqHandler) { - - CH_IRQ_PROLOGUE(); - - ServeInterrupt(); - - CH_IRQ_EPILOGUE(); -} - -/* - * EMAC subsystem initialization. - */ -void emac_init(int prio) { - int i; - - /* - * Buffers initialization. - */ -// received = 0; - for (i = 0; i < EMAC_RECEIVE_BUFFERS; i++) { - rent[i].w1 = (uint32_t)&rbuffers[i * EMAC_RECEIVE_BUFFERS_SIZE]; - rent[i].w2 = 0; - } - rent[EMAC_RECEIVE_BUFFERS - 1].w1 |= W1_R_WRAP; - rxptr = rent; - for (i = 0; i < EMAC_TRANSMIT_BUFFERS; i++) { - tent[i].w1 = (uint32_t)&tbuffers[i * EMAC_TRANSMIT_BUFFERS_SIZE]; - tent[i].w2 = EMAC_TRANSMIT_BUFFERS_SIZE | W2_T_USED; - } - tent[EMAC_TRANSMIT_BUFFERS - 1].w2 |= W2_T_WRAP; - txptr = tent; - - /* - * Disables the pullups on all the pins that are latched on reset by the PHY. - * The status latched into the PHY is: - * PHYADDR = 00001 - * PCS_LPBK = 0 (disabled) - * ISOLATE = 0 (disabled) - * RMIISEL = 0 (MII mode) - * RMIIBTB = 0 (BTB mode disabled) - * SPEED = 1 (100mbps) - * DUPLEX = 1 (full duplex) - * ANEG_EN = 1 (auto negotiation enabled) - */ - AT91C_BASE_PIOB->PIO_PPUDR = PHY_LATCHED_PINS; - - /* - * PHY power control. - */ - AT91C_BASE_PIOB->PIO_OER = PIOB_PHY_PD_MASK; // Becomes an output. - AT91C_BASE_PIOB->PIO_PPUDR = PIOB_PHY_PD_MASK; // Default pullup disabled. - AT91C_BASE_PIOB->PIO_SODR = PIOB_PHY_PD_MASK; // Output to high level. - - /* - * PHY reset by pulsing the NRST pin. - */ - AT91C_BASE_RSTC->RSTC_RMR = 0xA5000100; - AT91C_BASE_RSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST; - while (!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL)) - ; - - /* - * EMAC pins setup and clock enable. Note, PB18 is not included because it is - * used as #PD control and not as EF100. - */ - AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_EMAC; - AT91C_BASE_PIOB->PIO_ASR = EMAC_PIN_MASK; - AT91C_BASE_PIOB->PIO_PDR = EMAC_PIN_MASK; - AT91C_BASE_PIOB->PIO_PPUDR = EMAC_PIN_MASK; - - /* - * EMAC setup. - */ - AT91C_BASE_EMAC->EMAC_NCR = 0; // Initial setting. - AT91C_BASE_EMAC->EMAC_NCFGR = 2 << 10; // MDC-CLK = MCK / 32 - AT91C_BASE_EMAC->EMAC_USRIO = AT91C_EMAC_CLKEN; // Enable EMAC in MII mode - AT91C_BASE_EMAC->EMAC_RBQP = (AT91_REG)rent; // RX buffers list - AT91C_BASE_EMAC->EMAC_TBQP = (AT91_REG)tent; // TX buffers list - AT91C_BASE_EMAC->EMAC_RSR = AT91C_EMAC_OVR | - AT91C_EMAC_REC | - AT91C_EMAC_BNA; // Clears RSR - AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_DRFCS; // Initial NCFGR settings - AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TE | - AT91C_EMAC_RE | - AT91C_EMAC_CLRSTAT; // Initial NCR settings - EMACSetAddress(default_mac); - - /* - * PHY detection and settings. - */ - AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE; - if ((phy_get(MII_PHYSID1) != (MII_MICREL_ID >> 16)) || - ((phy_get(MII_PHYSID2) & 0xFFF0) != (MII_MICREL_ID & 0xFFF0))) - chSysHalt(); - - /* - * Waits for auto-negotiation to end and then detects the link status. - */ - AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; - - /* - * Interrupt setup. - */ - AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP; - AIC_ConfigureIT(AT91C_ID_EMAC, - AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | prio, - EMACIrqHandler); - AIC_EnableIT(AT91C_ID_EMAC); - - /* - * Event sources setup. - */ - chEvtInit(&EMACFrameTransmitted); - chEvtInit(&EMACFrameReceived); -} - -/* - * Set the MAC address. - */ -void EMACSetAddress(const uint8_t *eaddr) { - - AT91C_BASE_EMAC->EMAC_SA1L = (AT91_REG)((eaddr[3] << 24) | (eaddr[2] << 16) | - (eaddr[1] << 8) | eaddr[0]); - AT91C_BASE_EMAC->EMAC_SA1H = (AT91_REG)((eaddr[5] << 8) | eaddr[4]); -} - -/* - * Returns TRUE if the link is active. To be invoked at regular intervals in - * order to monitor the link. - * @note It is not thread-safe. - */ -bool_t EMACGetLinkStatus(void) { - uint32_t ncfgr, bmsr, bmcr, lpa; - - AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE; - (void)phy_get(MII_BMSR); - bmsr = phy_get(MII_BMSR); - if (!(bmsr & BMSR_LSTATUS)) { - AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; - return link_up = FALSE; - } - - ncfgr = AT91C_BASE_EMAC->EMAC_NCFGR & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); - bmcr = phy_get(MII_BMCR); - if (bmcr & BMCR_ANENABLE) { - lpa = phy_get(MII_LPA); - if (lpa & (LPA_100HALF | LPA_100FULL | LPA_100BASE4)) - ncfgr |= AT91C_EMAC_SPD; - if (lpa & (LPA_10FULL | LPA_100FULL)) - ncfgr |= AT91C_EMAC_FD; - } - else { - if (bmcr & BMCR_SPEED100) - ncfgr |= AT91C_EMAC_SPD; - if (bmcr & BMCR_FULLDPLX) - ncfgr |= AT91C_EMAC_FD; - } - AT91C_BASE_EMAC->EMAC_NCFGR = ncfgr; - AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; - return link_up = TRUE; -} - -/* - * Allocates and locks a buffer for a transmission operation. - */ -BufDescriptorEntry *EMACGetTransmitBuffer(void) { - BufDescriptorEntry *cptr; - - if (!link_up) - return NULL; - - chSysLock(); - cptr = txptr; - if (!(cptr->w2 & W2_T_USED) || - (cptr->w2 & W2_T_LOCKED)) { - chSysUnlock(); - return FALSE; - } - cptr->w2 |= W2_T_LOCKED; /* Locks the buffer while copying.*/ - if (++txptr >= &tent[EMAC_TRANSMIT_BUFFERS]) - txptr = tent; - chSysUnlock(); - return cptr; -} - -/* - * Transmits a previously allocated buffer and then releases it. - */ -void EMACTransmit(BufDescriptorEntry *cptr, size_t size) { - - chDbgAssert(size <= EMAC_TRANSMIT_BUFFERS_SIZE, - "EMACTransmit(), #1", - "unexpected size"); - - chSysLock(); - if (cptr < &tent[EMAC_TRANSMIT_BUFFERS - 1]) - cptr->w2 = size | W2_T_LAST_BUFFER; - else - cptr->w2 = size | W2_T_LAST_BUFFER | W2_T_WRAP; - AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART; - chSysUnlock(); -} - -/* - * Reads a buffered frame. - * Returns TRUE if a frame was present and read else FALSE. - * @note It is not thread-safe. - */ -bool_t EMACReceive(uint8_t *buf, size_t *sizep) { - unsigned n; - size_t size; - uint8_t *p; - bool_t overflow, found; - -// chSysLock(); -// if (received <= 0) { -// chSysUnlock(); -// return FALSE; -// } -// received--; -// chSysUnlock(); - - n = EMAC_RECEIVE_BUFFERS; - - /* - * Skips unused buffers, if any. - */ -skip: - while (n && !(rxptr->w1 & W1_R_OWNERSHIP)) { - if (++rxptr >= &rent[EMAC_RECEIVE_BUFFERS]) - rxptr = rent; - n--; - } - - /* - * Skips fragments, if any. - */ - while (n && (rxptr->w1 & W1_R_OWNERSHIP) && !(rxptr->w2 & W2_R_FRAME_START)) { - rxptr->w1 &= ~W1_R_OWNERSHIP; - if (++rxptr >= &rent[EMAC_RECEIVE_BUFFERS]) - rxptr = rent; - n--; - } - -restart: - p = buf; - size = 0; - found = overflow = FALSE; - while (n && !found) { - size_t segsize; - - if (!(rxptr->w1 & W1_R_OWNERSHIP)) - goto skip; /* Empty buffer for some reason... */ - - if (size && (rxptr->w2 & W2_R_FRAME_START)) - goto restart; /* Another start buffer for some reason... */ - - if (rxptr->w2 & W2_R_FRAME_END) { - segsize = (rxptr->w2 & W2_T_LENGTH_MASK) - size; - if (((rxptr->w2 & W2_T_LENGTH_MASK) > *sizep) || - (segsize > EMAC_RECEIVE_BUFFERS_SIZE)) - overflow = TRUE; - found = TRUE; - } - else { - segsize = EMAC_RECEIVE_BUFFERS_SIZE; - if (size + segsize > *sizep) - overflow = TRUE; - } - - if (!overflow) { - chDbgAssert(segsize <= 128, "EMACReceive(), #1", ""); - memcpy(p, (void *)(rxptr->w1 & W1_R_ADDRESS_MASK), segsize); - p += segsize; - size += segsize; - } - - rxptr->w1 &= ~W1_R_OWNERSHIP; - if (++rxptr >= &rent[EMAC_RECEIVE_BUFFERS]) - rxptr = rent; - n--; - } - - *sizep = size; - return found && !overflow; -} - -/** @} */ diff --git a/os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.h b/os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.h deleted file mode 100644 index de81fe4c6..000000000 --- a/os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file AT91SAM7X/sam7x_emac.h - * @brief AT91SAM7X EMAC driver macros and structures. - * @addtogroup AT91SAM7X_EMAC - * @{ - */ - -#ifndef _SAM7X_EMAC_H_ -#define _SAM7X_EMAC_H_ - -#define PHY_ADDRESS 1 - -#define EMAC_RECEIVE_BUFFERS 24 -#define EMAC_RECEIVE_BUFFERS_SIZE 128 -#define EMAC_TRANSMIT_BUFFERS 2 -#define EMAC_TRANSMIT_BUFFERS_SIZE 1518 - -typedef struct { - uint32_t w1; - uint32_t w2; -} BufDescriptorEntry; - -#define W1_R_OWNERSHIP 0x00000001 -#define W1_R_WRAP 0x00000002 -#define W1_R_ADDRESS_MASK 0xFFFFFFFC - -#define W2_R_LENGTH_MASK 0x00000FFF -#define W2_R_FRAME_START 0x00004000 -#define W2_R_FRAME_END 0x00008000 -#define W2_R_CFI 0x00010000 -#define W2_R_VLAN_PRIO_MASK 0x000E0000 -#define W2_R_PRIO_TAG_DETECTED 0x00100000 -#define W2_R_VLAN_TAG_DETECTED 0x00200000 -#define W2_R_TYPE_ID_MATCH 0x00400000 -#define W2_R_ADDR4_MATCH 0x00800000 -#define W2_R_ADDR3_MATCH 0x01000000 -#define W2_R_ADDR2_MATCH 0x02000000 -#define W2_R_ADDR1_MATCH 0x04000000 -#define W2_R_RFU1 0x08000000 -#define W2_R_ADDR_EXT_MATCH 0x10000000 -#define W2_R_UNICAST_MATCH 0x20000000 -#define W2_R_MULTICAST_MATCH 0x40000000 -#define W2_R_BROADCAST_DETECTED 0x80000000 - -#define W2_T_LENGTH_MASK 0x000007FF -#define W2_T_LOCKED 0x00000800 /* Not an EMAC flag, used by the driver */ -#define W2_T_RFU1 0x00003000 -#define W2_T_LAST_BUFFER 0x00008000 -#define W2_T_NO_CRC 0x00010000 -#define W2_T_RFU2 0x07FE0000 -#define W2_T_BUFFERS_EXHAUSTED 0x08000000 -#define W2_T_TRANSMIT_UNDERRUN 0x10000000 -#define W2_T_RETRY_LIMIT_EXC 0x20000000 -#define W2_T_WRAP 0x40000000 -#define W2_T_USED 0x80000000 - -#ifdef __cplusplus -extern "C" { -#endif - void emac_init(int prio); - void EMACSetAddress(const uint8_t *eaddr); - bool_t EMACGetLinkStatus(void); - BufDescriptorEntry *EMACGetTransmitBuffer(void); - void EMACTransmit(BufDescriptorEntry *cptr, size_t size); - bool_t EMACReceive(uint8_t *buf, size_t *sizep); -#ifdef __cplusplus -} -#endif - -extern EventSource EMACFrameTransmitted, EMACFrameReceived; - -#endif /* _SAM7X_EMAC_H_ */ - -/** @} */ diff --git a/os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.c b/os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.c deleted file mode 100644 index e0494633e..000000000 --- a/os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file AT91SAM7X/sam7x_serial.c - * @brief AT91SAM7X Serial driver code. - * @addtogroup AT91SAM7X_SERIAL - * @{ - */ - -#include - -#include "board.h" -#include "sam7x_serial.h" -#include "at91lib/aic.h" - -#if USE_SAM7X_USART0 || defined(__DOXYGEN__) -/** @brief USART0 serial driver identifier.*/ -FullDuplexDriver COM1; - -static uint8_t ib1[SERIAL_BUFFERS_SIZE]; -static uint8_t ob1[SERIAL_BUFFERS_SIZE]; -#endif - -#if USE_SAM7X_USART1 || defined(__DOXYGEN__) -/** @brief USART1 serial driver identifier.*/ -FullDuplexDriver COM2; - -static uint8_t ib2[SERIAL_BUFFERS_SIZE]; -static uint8_t ob2[SERIAL_BUFFERS_SIZE]; -#endif - -static void SetError(AT91_REG csr, FullDuplexDriver *com) { - dflags_t sts = 0; - - if (csr & AT91C_US_OVRE) - sts |= SD_OVERRUN_ERROR; - if (csr & AT91C_US_PARE) - sts |= SD_PARITY_ERROR; - if (csr & AT91C_US_FRAME) - sts |= SD_FRAMING_ERROR; - if (csr & AT91C_US_RXBRK) - sts |= SD_BREAK_DETECTED; - chSysLockFromIsr(); - chFDDAddFlagsI(com, sts); - chSysUnlockFromIsr(); -} - -/** @cond never*/ -__attribute__((noinline)) -/** @endcond*/ -/** - * @brief Common IRQ handler. - * @param[in] u pointer to an USART I/O block - * @param[in] com communication channel associated to the USART - */ -static void ServeInterrupt(AT91PS_USART u, FullDuplexDriver *com) { - - if (u->US_CSR & AT91C_US_RXRDY) { - chSysLockFromIsr(); - chFDDIncomingDataI(com, u->US_RHR); - chSysUnlockFromIsr(); - } - if (u->US_CSR & AT91C_US_TXRDY) { - chSysLockFromIsr(); - msg_t b = chFDDRequestDataI(com); - chSysUnlockFromIsr(); - if (b < Q_OK) - u->US_IDR = AT91C_US_TXRDY; - else - u->US_THR = b; - } - if (u->US_CSR & (AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE | AT91C_US_RXBRK)) { - SetError(u->US_CSR, com); - u->US_CR = AT91C_US_RSTSTA; - } - AT91C_BASE_AIC->AIC_EOICR = 0; -} - -#if USE_SAM7X_USART0 || defined(__DOXYGEN__) -CH_IRQ_HANDLER(USART0IrqHandler) { - - CH_IRQ_PROLOGUE(); - - ServeInterrupt(AT91C_BASE_US0, &COM1); - - CH_IRQ_EPILOGUE(); -} - -static void OutNotify1(void) { - - AT91C_BASE_US0->US_IER = AT91C_US_TXRDY; -} -#endif - -#if USE_SAM7X_USART1 || defined(__DOXYGEN__) -CH_IRQ_HANDLER(USART1IrqHandler) { - - CH_IRQ_PROLOGUE(); - - ServeInterrupt(AT91C_BASE_US1, &COM2); - - CH_IRQ_EPILOGUE(); -} - -static void OutNotify2(void) { - - AT91C_BASE_US1->US_IER = AT91C_US_TXRDY; -} -#endif - -/** - * @brief USART setup. - * @param[in] u pointer to an UART I/O block - * @param[in] speed serial port speed in bits per second - * @param[in] mr the value for the @p MR register - * @note Must be invoked with interrupts disabled. - * @note Does not reset the I/O queues. - */ -void usart_setup(AT91PS_USART u, int speed, int mr) { - - /* Disables IRQ sources and stop operations.*/ - u->US_IDR = 0xFFFFFFFF; - u->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RSTSTA; - - /* New parameters setup.*/ - if (mr & AT91C_US_OVER) - u->US_BRGR = MCK / (speed * 8); - else - u->US_BRGR = MCK / (speed * 16); - u->US_MR = mr; - u->US_RTOR = 0; - u->US_TTGR = 0; - - /* Enables operations and IRQ sources.*/ - u->US_CR = AT91C_US_RXEN | AT91C_US_TXEN | AT91C_US_DTREN | AT91C_US_RTSEN; - u->US_IER = AT91C_US_RXRDY | AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE | - AT91C_US_RXBRK; -} - -/** - * @brief Serial driver initialization. - * @param[in] prio0 priority to be assigned to the USART1 IRQ - * @param[in] prio1 priority to be assigned to the USART2 IRQ - * @note Handshake pads are not enabled inside this function because they - * may have another use, enable them externally if needed. - * RX and TX pads are handled inside. - */ -void serial_init(int prio0, int prio1) { - -#if USE_SAM7X_USART0 || defined(__DOXYGEN__) - /* I/O queue setup.*/ - chFDDInit(&COM1, ib1, sizeof ib1, NULL, ob1, sizeof ob1, OutNotify1); - - /* Switches the I/O pins to the peripheral function A, disables pullups.*/ - AT91C_BASE_PIOA->PIO_PDR = AT91C_PA0_RXD0 | AT91C_PA1_TXD0; - AT91C_BASE_PIOA->PIO_ASR = AT91C_PIO_PA0 | AT91C_PIO_PA1; - AT91C_BASE_PIOA->PIO_PPUDR = AT91C_PIO_PA0 | AT91C_PIO_PA1; - - /* Starts the clock and clears possible sources of immediate interrupts.*/ - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US0); - AT91C_BASE_US0->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RSTSTA; - - /* Interrupts setup.*/ - AIC_ConfigureIT(AT91C_ID_US0, - AT91C_AIC_SRCTYPE_HIGH_LEVEL | prio0, - USART0IrqHandler); - AIC_EnableIT(AT91C_ID_US0); - - /* Default parameters.*/ - usart_setup(AT91C_BASE_US0, DEFAULT_USART_BITRATE, - AT91C_US_USMODE_NORMAL | - AT91C_US_CLKS_CLOCK | - AT91C_US_CHRL_8_BITS | - AT91C_US_PAR_NONE | - AT91C_US_NBSTOP_1_BIT); -#endif - -#if USE_SAM7X_USART1 || defined(__DOXYGEN__) - /* I/O queues setup.*/ - chFDDInit(&COM2, ib2, sizeof ib2, NULL, ob2, sizeof ob2, OutNotify2); - - /* Switches the I/O pins to the peripheral function A, disables pullups.*/ - AT91C_BASE_PIOA->PIO_PDR = AT91C_PA5_RXD1 | AT91C_PA6_TXD1; - AT91C_BASE_PIOA->PIO_ASR = AT91C_PIO_PA5 | AT91C_PIO_PA6; - AT91C_BASE_PIOA->PIO_PPUDR = AT91C_PIO_PA5 | AT91C_PIO_PA6; - - /* Starts the clock and clears possible sources of immediate interrupts.*/ - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US1); - AT91C_BASE_US1->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RSTSTA; - - /* Interrupts setup.*/ - AIC_ConfigureIT(AT91C_ID_US1, - AT91C_AIC_SRCTYPE_HIGH_LEVEL | prio1, - USART1IrqHandler); - AIC_EnableIT(AT91C_ID_US1); - - /* Default parameters.*/ - usart_setup(AT91C_BASE_US1, DEFAULT_USART_BITRATE, - AT91C_US_USMODE_NORMAL | - AT91C_US_CLKS_CLOCK | - AT91C_US_CHRL_8_BITS | - AT91C_US_PAR_NONE | - AT91C_US_NBSTOP_1_BIT); -#endif -} - -/** @} */ diff --git a/os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.h b/os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.h deleted file mode 100644 index 67afe84be..000000000 --- a/os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file AT91SAM7X/sam7x_serial.h - * @brief AT91SAM7X Serial driver macros and structures. - * @addtogroup AT91SAM7X_SERIAL - * @{ - */ - -#ifndef _SAM7X_SERIAL_H_ -#define _SAM7X_SERIAL_H_ - -/** - * @brief Serial buffers size. - * @details Configuration parameter, you can change the depth of the queue - * buffers depending on the requirements of your application. - * @note The default is 128 bytes for both the transmission and receive buffers. - */ -#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) -#define SERIAL_BUFFERS_SIZE 128 -#endif - -/** - * @brief Default bit rate. - * @details Configuration parameter, at startup the UARTs are configured at - * this speed. - * @note It is possible to use @p SetUART() in order to change the working - * parameters at runtime. - */ -#if !defined(DEFAULT_USART_BITRATE) || defined(__DOXYGEN__) -#define DEFAULT_USART_BITRATE 38400 -#endif - -/** - * @brief UART0 driver enable switch. - * @details If set to @p TRUE the support for USART1 is included. - * @note The default is @p TRUE. - */ -#if !defined(USE_SAM7X_USART0) || defined(__DOXYGEN__) -#define USE_SAM7X_USART0 TRUE -#endif - -/** - * @brief UART1 driver enable switch. - * @details If set to @p TRUE the support for USART2 is included. - * @note The default is @p TRUE. - */ -#if !defined(USE_SAM7X_USART1) || defined(__DOXYGEN__) -#define USE_SAM7X_USART1 TRUE -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void serial_init(int prio0, int prio1); - void usart_setup(AT91PS_USART u, int speed, int mr); - CH_IRQ_HANDLER(UART0IrqHandler); - CH_IRQ_HANDLER(UART1IrqHandler); -#ifdef __cplusplus -} -#endif - -/** @cond never*/ -extern FullDuplexDriver COM1, COM2; -/** @endcond*/ - -#endif /* _SAM7X_SERIAL_H_ */ - -/** @} */ -- cgit v1.2.3