aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
Diffstat (limited to 'os')
-rw-r--r--os/hal/dox/uart.dox2
-rw-r--r--os/hal/include/adc.h8
-rw-r--r--os/hal/include/i2s.h148
-rw-r--r--os/hal/include/icu.h11
-rw-r--r--os/hal/include/mii.h42
-rw-r--r--os/hal/include/sdc.h12
-rw-r--r--os/hal/include/usb.h12
-rw-r--r--os/hal/platforms/AT91SAM7/ext_lld.c2
-rw-r--r--os/hal/platforms/AT91SAM7/mac_lld.c2
-rw-r--r--os/hal/platforms/AT91SAM7/serial_lld.c6
-rw-r--r--os/hal/platforms/AVR/serial_lld.h2
-rw-r--r--os/hal/platforms/SPC56x/hal_lld.c2
-rw-r--r--os/hal/platforms/STM32/GPIOv2/pal_lld.c2
-rw-r--r--os/hal/platforms/STM32/OTGv1/stm32_otg.h886
-rw-r--r--os/hal/platforms/STM32/OTGv1/usb_lld.c899
-rw-r--r--os/hal/platforms/STM32/OTGv1/usb_lld.h402
-rw-r--r--os/hal/platforms/STM32/can_lld.h2
-rw-r--r--os/hal/platforms/STM32/i2s_lld.c165
-rw-r--r--os/hal/platforms/STM32/i2s_lld.h321
-rw-r--r--os/hal/platforms/STM32/icu_lld.c16
-rw-r--r--os/hal/platforms/STM32/icu_lld.h4
-rw-r--r--os/hal/platforms/STM32/mac_lld.c39
-rw-r--r--os/hal/platforms/STM32/mac_lld.h35
-rw-r--r--os/hal/platforms/STM32/sdc_lld.c4
-rw-r--r--os/hal/platforms/STM32/serial_lld.h2
-rw-r--r--os/hal/platforms/STM32F1xx/platform.dox2
-rw-r--r--os/hal/platforms/STM32F1xx/stm32_dma.c2
-rw-r--r--os/hal/platforms/STM32F2xx/adc_lld.h4
-rw-r--r--os/hal/platforms/STM32F2xx/hal_lld.h4
-rw-r--r--os/hal/platforms/STM32F2xx/platform.dox2
-rw-r--r--os/hal/platforms/STM32F2xx/platform.mk7
-rw-r--r--os/hal/platforms/STM32F2xx/stm32_dma.c2
-rw-r--r--os/hal/platforms/STM32F2xx/stm32_rcc.h66
-rw-r--r--os/hal/platforms/STM32F4xx/adc_lld.h4
-rw-r--r--os/hal/platforms/STM32F4xx/hal_lld.h4
-rw-r--r--os/hal/platforms/STM32F4xx/platform.dox2
-rw-r--r--os/hal/platforms/STM32F4xx/platform.mk7
-rw-r--r--os/hal/platforms/STM32F4xx/stm32_dma.c2
-rw-r--r--os/hal/platforms/STM32F4xx/stm32_rcc.h66
-rw-r--r--os/hal/platforms/STM32L1xx/hal_lld.h10
-rw-r--r--os/hal/platforms/STM32L1xx/platform.dox2
-rw-r--r--os/hal/platforms/STM32L1xx/stm32_dma.c2
-rw-r--r--os/hal/platforms/STM32L1xx/stm32l1xx.h8
-rw-r--r--os/hal/platforms/STM8L/hal_lld.c2
-rw-r--r--os/hal/src/i2s.c179
-rw-r--r--os/hal/src/mmc_spi.c2
-rw-r--r--os/hal/templates/halconf.h2
-rw-r--r--os/hal/templates/icu_lld.h8
-rw-r--r--os/hal/templates/mac_lld.c2
-rw-r--r--os/kernel/include/chioch.h2
-rw-r--r--os/kernel/include/chmempools.h40
-rw-r--r--os/kernel/include/chschd.h2
-rw-r--r--os/kernel/include/chvt.h2
-rw-r--r--os/kernel/src/chevents.c2
-rw-r--r--os/kernel/src/chheap.c2
-rw-r--r--os/kernel/src/chmboxes.c1
-rw-r--r--os/kernel/src/chmempools.c38
-rw-r--r--os/kernel/src/chmtx.c6
-rw-r--r--os/kernel/src/chthreads.c2
-rw-r--r--os/kernel/templates/chconf.h2
-rw-r--r--os/kernel/templates/chcore.c2
-rw-r--r--os/ports/GCC/ARM/chcore.h2
-rw-r--r--os/ports/GCC/ARM/rules.mk15
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v6m.h12
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v7m.c22
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v7m.h14
-rw-r--r--os/ports/GCC/ARMCMx/crt0.c27
-rw-r--r--os/ports/GCC/ARMCMx/rules.mk15
-rw-r--r--os/ports/GCC/AVR/chcore.h2
-rw-r--r--os/ports/GCC/MSP430/chcore.h2
-rw-r--r--os/ports/IAR/ARMCMx/chcore_v6m.h12
-rw-r--r--os/ports/IAR/ARMCMx/chcore_v7m.h14
-rw-r--r--os/ports/RC/STM8/chcore.h2
-rw-r--r--os/ports/RVCT/ARMCMx/chcore_v6m.h12
-rw-r--r--os/ports/RVCT/ARMCMx/chcore_v7m.h14
-rw-r--r--os/ports/cosmic/STM8/chcore.h2
-rw-r--r--os/various/chprintf.c56
-rw-r--r--os/various/chprintf.h7
-rw-r--r--[-rwxr-xr-x]os/various/chrtclib.c0
-rw-r--r--[-rwxr-xr-x]os/various/chrtclib.h0
-rwxr-xr-xos/various/diskio.c244
-rw-r--r--os/various/evtimer.h8
-rw-r--r--os/various/mail.c96
-rw-r--r--os/various/mail.h59
84 files changed, 3949 insertions, 206 deletions
diff --git a/os/hal/dox/uart.dox b/os/hal/dox/uart.dox
index 079237982..27c1494fb 100644
--- a/os/hal/dox/uart.dox
+++ b/os/hal/dox/uart.dox
@@ -39,7 +39,7 @@
* - Multipoint network drivers.
* - Serial protocol decoders.
* .
- * If your application requires a synchronoyus buffered driver then
+ * If your application requires a synchronous buffered driver then
* the @ref SERIAL should be used instead.
* @pre In order to use the UART driver the @p HAL_USE_UART option
* must be enabled in @p halconf.h.
diff --git a/os/hal/include/adc.h b/os/hal/include/adc.h
index 137096609..8f829d386 100644
--- a/os/hal/include/adc.h
+++ b/os/hal/include/adc.h
@@ -282,13 +282,13 @@ extern "C" {
void adcStart(ADCDriver *adcp, const ADCConfig *config);
void adcStop(ADCDriver *adcp);
void adcStartConversion(ADCDriver *adcp,
+ const ADCConversionGroup *grpp,
+ adcsample_t *samples,
+ size_t depth);
+ void adcStartConversionI(ADCDriver *adcp,
const ADCConversionGroup *grpp,
adcsample_t *samples,
size_t depth);
- void adcStartConversionI(ADCDriver *adcp,
- const ADCConversionGroup *grpp,
- adcsample_t *samples,
- size_t depth);
void adcStopConversion(ADCDriver *adcp);
void adcStopConversionI(ADCDriver *adcp);
#if ADC_USE_WAIT
diff --git a/os/hal/include/i2s.h b/os/hal/include/i2s.h
new file mode 100644
index 000000000..d2dedf982
--- /dev/null
+++ b/os/hal/include/i2s.h
@@ -0,0 +1,148 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file i2s.h
+ * @brief I2S Driver macros and structures.
+ *
+ * @addtogroup I2S
+ * @{
+ */
+
+#ifndef _I2S_H_
+#define _I2S_H_
+
+#if HAL_USE_I2S || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name I2S modes
+ * @{
+ */
+#define I2S_MODE_SLAVE 0
+#define I2S_MODE_MASTER 1
+#define I2S_MODE_TX 2
+#define I2S_MODE_RX 4
+#define I2S_MODE_TXRX (I2S_MODE_TX | I2S_MODE_RX)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ I2S_UNINIT = 0, /**< Not initialized. */
+ I2S_STOP = 1, /**< Stopped. */
+ I2S_READY = 2, /**< Ready. */
+ I2S_ACTIVE = 3, /**< Active. */
+ I2S_COMPLETE = 4 /**< Transmission complete. */
+} i2sstate_t;
+
+/**
+ * @brief Type of a structure representing a I2S driver.
+ */
+typedef struct I2SDriver I2SDriver;
+
+#include "i2s_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Starts a I2S data exchange.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @iclass
+ */
+#define i2sStartExchangeI(i2sp) { \
+ i2s_lld_start_exchange(i2sp); \
+ (i2sp)->state = I2S_ACTIVE; \
+}
+
+/**
+ * @brief Starts a I2S data exchange in continuous mode.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @iclass
+ */
+#define i2sStartExchangeContinuousI(i2sp) { \
+ i2s_lld_start_exchange_continuous(i2sp); \
+ (i2sp)->state = I2S_ACTIVE; \
+}
+
+/**
+ * @brief Stops the ongoing data exchange.
+ * @details The ongoing data exchange, if any, is stopped, if the driver
+ * was not active the function does nothing.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @iclass
+ */
+#define i2sStopExchangeI(i2sp) { \
+ i2s_lld_stop_exchange(i2sp); \
+ (i2sp)->state = I2S_READY; \
+}
+
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void i2sInit(void);
+ void i2sObjectInit(I2SDriver *i2sp);
+ void i2sStart(I2SDriver *i2sp, const I2SConfig *config);
+ void i2sStop(I2SDriver *i2sp);
+ void i2sStartExchange(I2SDriver *i2sp);
+ void i2sStopExchange(I2SDriver *i2sp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_I2S */
+
+#endif /* _I2S_H_ */
+
+/** @} */
diff --git a/os/hal/include/icu.h b/os/hal/include/icu.h
index 99cfc4e3c..15a9b2380 100644
--- a/os/hal/include/icu.h
+++ b/os/hal/include/icu.h
@@ -157,6 +157,17 @@ typedef void (*icucallback_t)(ICUDriver *icup);
if (previous_state != ICU_WAITING) \
(icup)->config->period_cb(icup); \
}
+
+/**
+ * @brief Common ISR code, ICU timer overflow event.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+#define _icu_isr_invoke_overflow_cb(icup) { \
+ (icup)->config->overflow_cb(icup); \
+}
/** @} */
/*===========================================================================*/
diff --git a/os/hal/include/mii.h b/os/hal/include/mii.h
index 0ae3a9b30..ef4acbd26 100644
--- a/os/hal/include/mii.h
+++ b/os/hal/include/mii.h
@@ -40,9 +40,12 @@
#define MII_ADVERTISE 0x04 /**< Advertisement control reg. */
#define MII_LPA 0x05 /**< Link partner ability reg. */
#define MII_EXPANSION 0x06 /**< Expansion register. */
+#define MII_ANNPTR 0x07 /**< 1000BASE-T control. */
#define MII_CTRL1000 0x09 /**< 1000BASE-T control. */
#define MII_STAT1000 0x0a /**< 1000BASE-T status. */
#define MII_ESTATUS 0x0f /**< Extended Status. */
+#define MII_PHYSTS 0x10 /**< PHY Status register. */
+#define MII_MICR 0x11 /**< MII Interrupt ctrl register. */
#define MII_DCOUNTER 0x12 /**< Disconnect counter. */
#define MII_FCSCOUNTER 0x13 /**< False carrier counter. */
#define MII_NWAYTEST 0x14 /**< N-way auto-neg test reg. */
@@ -52,14 +55,13 @@
#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_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_RESV 0x007f /**< Unused. */
#define BMCR_CTST 0x0080 /**< Collision test. */
#define BMCR_FULLDPLX 0x0100 /**< Full duplex. */
#define BMCR_ANRESTART 0x0200 /**< Auto negotiation restart. */
@@ -67,7 +69,7 @@
#define BMCR_PDOWN 0x0800 /**< Powerdown. */
#define BMCR_ANENABLE 0x1000 /**< Enable auto negotiation. */
#define BMCR_SPEED100 0x2000 /**< Select 100Mbps. */
-#define BMCR_LOOPBACK 0x4000 /**< TXD loopback bits. */
+#define BMCR_LOOPBACK 0x4000 /**< TXD loopback bit. */
#define BMCR_RESET 0x8000 /**< Reset. */
/*
@@ -79,10 +81,8 @@
#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_MFPRESUPPCAP 0x0040 /**< Able to suppress preamble. */
+#define BMSR_RESV 0x0780 /**< Unused. */
#define BMSR_10HALF 0x0800 /**< Can do 10mbps, half-duplex. */
#define BMSR_10FULL 0x1000 /**< Can do 10mbps, full-duplex. */
#define BMSR_100HALF 0x2000 /**< Can do 100mbps, half-duplex. */
@@ -95,13 +95,9 @@
#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. */
@@ -120,13 +116,9 @@
*/
#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. */
@@ -148,9 +140,6 @@
#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.
*/
@@ -159,26 +148,13 @@
#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.*/
-
-/*
* PHY identifiers.
*/
#define MII_DM9161_ID 0x0181b8a0
#define MII_AM79C875_ID 0x00225540
#define MII_KS8721_ID 0x00221610
#define MII_STE101P_ID 0x00061C50
+#define MII_DP83848I_ID 0x20005C90
#endif /* _MII_H_ */
diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h
index aa02e4f5b..0e44361ff 100644
--- a/os/hal/include/sdc.h
+++ b/os/hal/include/sdc.h
@@ -113,7 +113,7 @@
*/
/**
* @brief Number of initialization attempts before rejecting the card.
- * @note Attempts are performed at 10mS intevals.
+ * @note Attempts are performed at 10mS intervals.
*/
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
#define SDC_INIT_RETRY 100
@@ -254,6 +254,16 @@ typedef enum {
#define sdcIsWriteProtected(sdcp) (sdc_lld_is_write_protected(sdcp))
/**
+ * @brief Returns the card capacity in blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The card capacity.
+ *
+ * @api
+ */
+#define sdcGetCardCapacity(sdcp) ((sdcp)->capacity)
+
+/**
* @brief Slice position of values in CSD register.
*/
/* CSD version 2.0 */
diff --git a/os/hal/include/usb.h b/os/hal/include/usb.h
index e261e9486..9e5eb1b62 100644
--- a/os/hal/include/usb.h
+++ b/os/hal/include/usb.h
@@ -323,11 +323,15 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
*/
/**
* @brief Connects the USB device.
+ *
+ * @api
*/
#define usbConnectBus(usbp) usb_lld_connect_bus(usbp)
/**
* @brief Disconnect the USB device.
+ *
+ * @api
*/
#define usbDisconnectBus(usbp) usb_lld_disconnect_bus(usbp)
@@ -369,7 +373,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
/**
* @brief Reads from a dedicated packet buffer.
- * @pre In order to use this function he endpoint must have been
+ * @pre In order to use this function the endpoint must have been
* initialized in packet mode.
* @note This function can be invoked both in thread and IRQ context.
*
@@ -389,7 +393,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
/**
* @brief Writes to a dedicated packet buffer.
- * @pre In order to use this function he endpoint must have been
+ * @pre In order to use this function the endpoint must have been
* initialized in packet mode.
* @note This function can be invoked both in thread and IRQ context.
*
@@ -406,7 +410,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
/**
* @brief Prepares for a receive transaction on an OUT endpoint.
- * @pre In order to use this function he endpoint must have been
+ * @pre In order to use this function the endpoint must have been
* initialized in transaction mode.
* @post The endpoint is ready for @p usbStartReceiveI().
*
@@ -422,7 +426,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
/**
* @brief Prepares for a transmit transaction on an IN endpoint.
- * @pre In order to use this function he endpoint must have been
+ * @pre In order to use this function the endpoint must have been
* initialized in transaction mode.
* @post The endpoint is ready for @p usbStartTransmitI().
*
diff --git a/os/hal/platforms/AT91SAM7/ext_lld.c b/os/hal/platforms/AT91SAM7/ext_lld.c
index fc362235e..98f08c9b8 100644
--- a/os/hal/platforms/AT91SAM7/ext_lld.c
+++ b/os/hal/platforms/AT91SAM7/ext_lld.c
@@ -146,7 +146,7 @@ void ext_lld_init(void) {
#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
(SAM7_PLATFORM == SAM7X512)
- /* Aame for PIOB.*/
+ /* Same for PIOB.*/
extObjectInit(&EXTDB);
EXTDB.pio = AT91C_BASE_PIOB;
EXTDB.pid = AT91C_ID_PIOB;
diff --git a/os/hal/platforms/AT91SAM7/mac_lld.c b/os/hal/platforms/AT91SAM7/mac_lld.c
index b4555194b..dd1d6c6bd 100644
--- a/os/hal/platforms/AT91SAM7/mac_lld.c
+++ b/os/hal/platforms/AT91SAM7/mac_lld.c
@@ -324,7 +324,7 @@ msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
* @brief Writes to a transmit descriptor's stream.
*
* @param[in] tdp pointer to a @p MACTransmitDescriptor structure
- * @param[in] buf pointer to the buffer cointaining the data to be
+ * @param[in] buf pointer to the buffer containing the data to be
* written
* @param[in] size number of bytes to be written
* @return The number of bytes written into the descriptor's
diff --git a/os/hal/platforms/AT91SAM7/serial_lld.c b/os/hal/platforms/AT91SAM7/serial_lld.c
index 6f1bbb1bf..d23aa9b0e 100644
--- a/os/hal/platforms/AT91SAM7/serial_lld.c
+++ b/os/hal/platforms/AT91SAM7/serial_lld.c
@@ -31,7 +31,8 @@
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
-#if SAM7_PLATFORM == SAM7S256
+#if (SAM7_PLATFORM == SAM7S64) || (SAM7_PLATFORM == SAM7S128) || \
+ (SAM7_PLATFORM == SAM7S256) || (SAM7_PLATFORM == SAM7S512)
#define SAM7_USART0_RX AT91C_PA5_RXD0
#define SAM7_USART0_TX AT91C_PA6_TXD0
@@ -40,7 +41,8 @@
#define SAM7_DBGU_RX AT91C_PA9_DRXD
#define SAM7_DBGU_TX AT91C_PA10_DTXD
-#elif SAM7_PLATFORM == SAM7X256
+#elif (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
+ (SAM7_PLATFORM == SAM7X512)
#define SAM7_USART0_RX AT91C_PA0_RXD0
#define SAM7_USART0_TX AT91C_PA1_TXD0
diff --git a/os/hal/platforms/AVR/serial_lld.h b/os/hal/platforms/AVR/serial_lld.h
index bcaea51c1..f7bea9568 100644
--- a/os/hal/platforms/AVR/serial_lld.h
+++ b/os/hal/platforms/AVR/serial_lld.h
@@ -109,7 +109,7 @@ typedef struct {
#define UBRR(b) (((F_CPU / b) >> 4) - 1)
/**
- * @brief Macro for baud rate computationwhen U2Xn == 1.
+ * @brief Macro for baud rate computation when U2Xn == 1.
* @note Make sure the final baud rate is within tolerance.
*/
#define UBRR2(b) (((F_CPU / b) >> 3) - 1)
diff --git a/os/hal/platforms/SPC56x/hal_lld.c b/os/hal/platforms/SPC56x/hal_lld.c
index 3b8e8bc93..f5dec4516 100644
--- a/os/hal/platforms/SPC56x/hal_lld.c
+++ b/os/hal/platforms/SPC56x/hal_lld.c
@@ -70,7 +70,7 @@ void hal_lld_init(void) {
/* Optimal crossbar settings. The DMA priority is placed above the CPU
priority in order to not starve I/O activities while the CPU is
- excuting tight loops (FLASH and SRAM slave ports only).
+ executing tight loops (FLASH and SRAM slave ports only).
The SRAM is parked on the load/store port, for some unknown reason it
is defaulted on the instructions port and this kills performance.*/
XBAR.SGPCR3.B.PARK = 4; /* RAM slave on load/store port.*/
diff --git a/os/hal/platforms/STM32/GPIOv2/pal_lld.c b/os/hal/platforms/STM32/GPIOv2/pal_lld.c
index dfaa8da2f..dfe29dd17 100644
--- a/os/hal/platforms/STM32/GPIOv2/pal_lld.c
+++ b/os/hal/platforms/STM32/GPIOv2/pal_lld.c
@@ -50,7 +50,7 @@
RCC_AHB1ENR_GPIOIEN)
#define AHB1_LPEN_MASK AHB1_EN_MASK
#else
-#error "missing or usupported platform for GPIOv2 PAL driver"
+#error "missing or unsupported platform for GPIOv2 PAL driver"
#endif
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/OTGv1/stm32_otg.h b/os/hal/platforms/STM32/OTGv1/stm32_otg.h
new file mode 100644
index 000000000..083f868a5
--- /dev/null
+++ b/os/hal/platforms/STM32/OTGv1/stm32_otg.h
@@ -0,0 +1,886 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file stm32_otg.h
+ * @brief STM32 OTG registers layout header.
+ *
+ * @addtogroup USB
+ * @{
+ */
+
+#ifndef _STM32_OTG_H_
+#define _STM32_OTG_H_
+
+/**
+ * @brief Number of the implemented endpoints.
+ * @details This value does not include the endpoint 0 that is always present.
+ */
+#define STM32_OTG_ENDOPOINTS_NUMBER 3
+
+/**
+ * @brief FIFO memory size in words.
+ */
+#define STM32_OTG_FIFO_MEM_SIZE 384
+
+/**
+ * @brief Host channel registers group.
+ */
+typedef struct {
+ volatile uint32_t HCCHAR; /**< @brief Host channel characteristics
+ register. */
+ volatile uint32_t resvd8;
+ volatile uint32_t HCINT; /**< @brief Host channel interrupt register.*/
+ volatile uint32_t HCINTMSK; /**< @brief Host channel interrupt mask
+ register. */
+ volatile uint32_t HCTSIZ; /**< @brief Host channel transfer size
+ register. */
+ volatile uint32_t resvd14;
+ volatile uint32_t resvd18;
+ volatile uint32_t resvd1c;
+} stm32_otg_host_chn_t;
+
+/**
+ * @brief Device input endpoint registers group.
+ */
+typedef struct {
+ volatile uint32_t DIEPCTL; /**< @brief Device control IN endpoint
+ control register. */
+ volatile uint32_t resvd4;
+ volatile uint32_t DIEPINT; /**< @brief Device IN endpoint interrupt
+ register. */
+ volatile uint32_t resvdC;
+ volatile uint32_t DIEPTSIZ; /**< @brief Device IN endpoint transfer size
+ register. */
+ volatile uint32_t resvd14;
+ volatile uint32_t DTXFSTS; /**< @brief Device IN endpoint transmit FIFO
+ status register. */
+ volatile uint32_t resvd1C;
+} stm32_otg_in_ep_t;
+
+/**
+ * @brief Device output endpoint registers group.
+ */
+typedef struct {
+ volatile uint32_t DOEPCTL; /**< @brief Device control OUT endpoint
+ control register. */
+ volatile uint32_t resvd4;
+ volatile uint32_t DOEPINT; /**< @brief Device OUT endpoint interrupt
+ register. */
+ volatile uint32_t resvdC;
+ volatile uint32_t DOEPTSIZ; /**< @brief Device OUT endpoint transfer
+ size register. */
+ volatile uint32_t resvd14;
+ volatile uint32_t resvd18;
+ volatile uint32_t resvd1C;
+} stm32_otg_out_ep_t;
+
+/**
+ * @brief USB registers memory map.
+ */
+typedef struct {
+ volatile uint32_t GOTGCTL; /**< @brief OTG control and status register.*/
+ volatile uint32_t GOTGINT; /**< @brief OTG interrupt register. */
+ volatile uint32_t GAHBCFG; /**< @brief AHB configuration register. */
+ volatile uint32_t GUSBCFG; /**< @brief USB configuration register. */
+ volatile uint32_t GRSTCTL; /**< @brief Reset register size. */
+ volatile uint32_t GINTSTS; /**< @brief Interrupt register. */
+ volatile uint32_t GINTMSK; /**< @brief Interrupt mask register. */
+ volatile uint32_t GRXSTSR; /**< @brief Receive status debug read
+ register. */
+ volatile uint32_t GRXSTSP; /**< @brief Receive status read/pop
+ register. */
+ volatile uint32_t GRXFSIZ; /**< @brief Receive FIFO size register. */
+ volatile uint32_t DIEPTXF0; /**< @brief Endpoint 0 transmit FIFO size
+ register. */
+ volatile uint32_t HNPTXSTS; /**< @brief Non-periodic transmit FIFO/queue
+ status register. */
+ volatile uint32_t resvd30;
+ volatile uint32_t resvd34;
+ volatile uint32_t GCCFG; /**< @brief General core configuration. */
+ volatile uint32_t CID; /**< @brief Core ID register. */
+ volatile uint32_t resvd58[48];
+ volatile uint32_t HPTXFSIZ; /**< @brief Host periodic transmit FIFO size
+ register. */
+ volatile uint32_t DIEPTXF[15];/**< @brief Device IN endpoint transmit FIFO
+ size registers. */
+ volatile uint32_t resvd140[176];
+ volatile uint32_t HCFG; /**< @brief Host configuration register. */
+ volatile uint32_t HFIR; /**< @brief Host frame interval register. */
+ volatile uint32_t HFNUM; /**< @brief Host frame number/frame time
+ Remaining register. */
+ volatile uint32_t resvd40C;
+ volatile uint32_t HPTXSTS; /**< @brief Host periodic transmit FIFO/queue
+ status register. */
+ volatile uint32_t HAINT; /**< @brief Host all channels interrupt
+ register. */
+ volatile uint32_t HAINTMSK; /**< @brief Host all channels interrupt mask
+ register. */
+ volatile uint32_t resvd41C[9];
+ volatile uint32_t HPRT; /**< @brief Host port control and status
+ register. */
+ volatile uint32_t resvd444[47];
+ stm32_otg_host_chn_t hc[16]; /**< @brief Host channels array. */
+ volatile uint32_t resvd700[64];
+ volatile uint32_t DCFG; /**< @brief Device configuration register. */
+ volatile uint32_t DCTL; /**< @brief Device control register. */
+ volatile uint32_t DSTS; /**< @brief Device status register. */
+ volatile uint32_t resvd80C;
+ volatile uint32_t DIEPMSK; /**< @brief Device IN endpoint common
+ interrupt mask register. */
+ volatile uint32_t DOEPMSK; /**< @brief Device OUT endpoint common
+ interrupt mask register. */
+ volatile uint32_t DAINT; /**< @brief Device all endpoints interrupt
+ register. */
+ volatile uint32_t DAINTMSK; /**< @brief Device all endpoints interrupt
+ mask register. */
+ volatile uint32_t resvd820;
+ volatile uint32_t resvd824;
+ volatile uint32_t DVBUSDIS; /**< @brief Device VBUS discharge time
+ register. */
+ volatile uint32_t DVBUSPULSE; /**< @brief Device VBUS pulsing time
+ register. */
+ volatile uint32_t resvd830;
+ volatile uint32_t DIEPEMPMSK; /**< @brief Device IN endpoint FIFO empty
+ interrupt mask register. */
+ volatile uint32_t resvd838;
+ volatile uint32_t resvd83C;
+ volatile uint32_t resvd840[16];
+ volatile uint32_t resvd880[16];
+ volatile uint32_t resvd8C0[16];
+ stm32_otg_in_ep_t ie[16]; /**< @brief Input endpoints. */
+ stm32_otg_out_ep_t oe[16]; /**< @brief Output endpoints. */
+ volatile uint32_t resvdD00[64];
+ volatile uint32_t PCGCCTL; /**< @brief Power and clock gating control
+ register. */
+ volatile uint32_t resvdE04[127];
+} stm32_otg_t;
+
+/**
+ * @name GOTGCTL register bit definitions
+ * @{
+ */
+#define GOTGCTL_BSVLD (1U<<19) /**< B-Session Valid. */
+#define GOTGCTL_ASVLD (1U<<18) /**< A-Session Valid. */
+#define GOTGCTL_DBCT (1U<<17) /**< Long/Short debounce time. */
+#define GOTGCTL_CIDSTS (1U<<16) /**< Connector ID status. */
+#define GOTGCTL_DHNPEN (1U<<11) /**< Device HNP enabled. */
+#define GOTGCTL_HSHNPEN (1U<<10) /**< Host Set HNP enable. */
+#define GOTGCTL_HNPRQ (1U<<9) /**< HNP request. */
+#define GOTGCTL_HNGSCS (1U<<8) /**< Host negotiation success. */
+#define GOTGCTL_SRQ (1U<<1) /**< Session request. */
+#define GOTGCTL_SRQSCS (1U<<0) /**< Session request success. */
+/** @} */
+
+/**
+ * @name GOTGINT register bit definitions
+ * @{
+ */
+#define GOTGINT_DBCDNE (1U<<19) /**< Debounce done. */
+#define GOTGINT_ADTOCHG (1U<<18) /**< A-Device timeout change. */
+#define GOTGINT_HNGDET (1U<<17) /**< Host negotiation detected. */
+#define GOTGINT_HNSSCHG (1U<<9) /**< Host negotiation success
+ status change. */
+#define GOTGINT_SRSSCHG (1U<<8) /**< Session request success
+ status change. */
+#define GOTGINT_SEDET (1U<<2) /**< Session end detected. */
+/** @} */
+
+/**
+ * @name GAHBCFG register bit definitions
+ * @{
+ */
+#define GAHBCFG_PTXFELVL (1U<<8) /**< Periodic TxFIFO empty
+ level. */
+#define GAHBCFG_TXFELVL (1U<<7) /**< Non-periodic TxFIFO empty
+ level. */
+#define GAHBCFG_GINTMSK (1U<<0) /**< Global interrupt mask. */
+/** @} */
+
+/**
+ * @name GUSBCFG register bit definitions
+ * @{
+ */
+#define GUSBCFG_CTXPKT (1U<<31) /**< Corrupt Tx packet. */
+#define GUSBCFG_FDMOD (1U<<30) /**< Force Device Mode. */
+#define GUSBCFG_FHMOD (1U<<29) /**< Force Host Mode. */
+#define GUSBCFG_TRDT_MASK (15U<<10) /**< USB Turnaround time field
+ mask. */
+#define GUSBCFG_TRDT(n) ((n)<<10) /**< USB Turnaround time field
+ value. */
+#define GUSBCFG_HNPCAP (1U<<9) /**< HNP-Capable. */
+#define GUSBCFG_SRPCAP (1U<<8) /**< SRP-Capable. */
+#define GUSBCFG_PHYSEL (1U<<6) /**< USB 2.0 High-Speed PHY or
+ USB 1.1 Full-Speed serial
+ transceiver Select. */
+#define GUSBCFG_TOCAL_MASK (7U<<0) /**< HS/FS timeout calibration
+ field mask. */
+#define GUSBCFG_TOCAL(n) ((n)<<0) /**< HS/FS timeout calibration
+ field value. */
+/** @} */
+
+/**
+ * @name GRSTCTL register bit definitions
+ * @{
+ */
+#define GRSTCTL_AHBIDL (1U<<31) /**< AHB Master Idle. */
+#define GRSTCTL_TXFNUM_MASK (31U<<6) /**< TxFIFO number field mask. */
+#define GRSTCTL_TXFNUM(n) ((n)<<6) /**< TxFIFO number field value. */
+#define GRSTCTL_TXFFLSH (1U<<5) /**< TxFIFO flush. */
+#define GRSTCTL_RXFFLSH (1U<<4) /**< RxFIFO flush. */
+#define GRSTCTL_FCRST (1U<<2) /**< Host frame counter reset. */
+#define GRSTCTL_HSRST (1U<<1) /**< HClk soft reset. */
+#define GRSTCTL_CSRST (1U<<0) /**< Core soft reset. */
+/** @} */
+
+/**
+ * @name GINTSTS register bit definitions
+ * @{
+ */
+#define GINTSTS_WKUPINT (1U<<31) /**< Resume/Remote wakeup
+ detected interrupt. */
+#define GINTSTS_SRQINT (1U<<30) /**< Session request/New session
+ detected interrupt. */
+#define GINTSTS_DISCINT (1U<<29) /**< Disconnect detected
+ interrupt. */
+#define GINTSTS_CIDSCHG (1U<<28) /**< Connector ID status change.*/
+#define GINTSTS_PTXFE (1U<<26) /**< Periodic TxFIFO empty. */
+#define GINTSTS_HCINT (1U<<25) /**< Host channels interrupt. */
+#define GINTSTS_HPRTINT (1U<<24) /**< Host port interrupt. */
+#define GINTSTS_IPXFR (1U<<21) /**< Incomplete periodic
+ transfer. */
+#define GINTSTS_IISOOXFR (1U<<21) /**< Incomplete isochronous OUT
+ transfer. */
+#define GINTSTS_IISOIXFR (1U<<20) /**< Incomplete isochronous IN
+ transfer. */
+#define GINTSTS_OEPINT (1U<<19) /**< OUT endpoints interrupt. */
+#define GINTSTS_IEPINT (1U<<18) /**< IN endpoints interrupt. */
+#define GINTSTS_EOPF (1U<<15) /**< End of periodic frame
+ interrupt. */
+#define GINTSTS_ISOODRP (1U<<14) /**< Isochronous OUT packet
+ dropped interrupt. */
+#define GINTSTS_ENUMDNE (1U<<13) /**< Enumeration done. */
+#define GINTSTS_USBRST (1U<<12) /**< USB reset. */
+#define GINTSTS_USBSUSP (1U<<11) /**< USB suspend. */
+#define GINTSTS_ESUSP (1U<<10) /**< Early suspend. */
+#define GINTSTS_GONAKEFF (1U<<7) /**< Global OUT NAK effective. */
+#define GINTSTS_GINAKEFF (1U<<6) /**< Global IN non-periodic NAK
+ effective. */
+#define GINTSTS_NPTXFE (1U<<5) /**< Non-periodic TxFIFO empty. */
+#define GINTSTS_RXFLVL (1U<<4) /**< RxFIFO non-empty. */
+#define GINTSTS_SOF (1U<<3) /**< Start of frame. */
+#define GINTSTS_OTGINT (1U<<2) /**< OTG interrupt. */
+#define GINTSTS_MMIS (1U<<1) /**< Mode Mismatch interrupt. */
+#define GINTSTS_CMOD (1U<<0) /**< Current mode of operation. */
+/** @} */
+
+/**
+ * @name GINTMSK register bit definitions
+ * @{
+ */
+#define GINTMSK_WKUM (1U<<31) /**< Resume/remote wakeup
+ detected interrupt mask. */
+#define GINTMSK_SRQM (1U<<30) /**< Session request/New session
+ detected interrupt mask. */
+#define GINTMSK_DISCM (1U<<29) /**< Disconnect detected
+ interrupt mask. */
+#define GINTMSK_CIDSCHGM (1U<<28) /**< Connector ID status change
+ mask. */
+#define GINTMSK_PTXFEM (1U<<26) /**< Periodic TxFIFO empty mask.*/
+#define GINTMSK_HCM (1U<<25) /**< Host channels interrupt
+ mask. */
+#define GINTMSK_HPRTM (1U<<24) /**< Host port interrupt mask. */
+#define GINTMSK_IPXFRM (1U<<21) /**< Incomplete periodic
+ transfer mask. */
+#define GINTMSK_IISOOXFRM (1U<<21) /**< Incomplete isochronous OUT
+ transfer mask. */
+#define GINTMSK_IISOIXFRM (1U<<20) /**< Incomplete isochronous IN
+ transfer mask. */
+#define GINTMSK_OEPM (1U<<19) /**< OUT endpoints interrupt
+ mask. */
+#define GINTMSK_IEPM (1U<<18) /**< IN endpoints interrupt
+ mask. */
+#define GINTMSK_EOPFM (1U<<15) /**< End of periodic frame
+ interrupt mask. */
+#define GINTMSK_ISOODRPM (1U<<14) /**< Isochronous OUT packet
+ dropped interrupt mask. */
+#define GINTMSK_ENUMDNEM (1U<<13) /**< Enumeration done mask. */
+#define GINTMSK_USBRSTM (1U<<12) /**< USB reset mask. */
+#define GINTMSK_USBSUSPM (1U<<11) /**< USB suspend mask. */
+#define GINTMSK_ESUSPM (1U<<10) /**< Early suspend mask. */
+#define GINTMSK_GONAKEFFM (1U<<7) /**< Global OUT NAK effective
+ mask. */
+#define GINTMSK_GINAKEFFM (1U<<6) /**< Global non-periodic IN NAK
+ effective mask. */
+#define GINTMSK_NPTXFEM (1U<<5) /**< Non-periodic TxFIFO empty
+ mask. */
+#define GINTMSK_RXFLVLM (1U<<4) /**< Receive FIFO non-empty
+ mask. */
+#define GINTMSK_SOFM (1U<<3) /**< Start of (micro)frame mask.*/
+#define GINTMSK_OTGM (1U<<2) /**< OTG interrupt mask. */
+#define GINTMSK_MMISM (1U<<1) /**< Mode Mismatch interrupt
+ mask. */
+/** @} */
+
+/**
+ * @name GRXSTSR register bit definitions
+ * @{
+ */
+#define GRXSTSR_PKTSTS_MASK (15U<<17) /**< Packet status mask. */
+#define GRXSTSR_PKTSTS(n) ((n)<<17) /**< Packet status value. */
+#define GRXSTSR_OUT_GLOBAL_NAK GRXSTSR_PKTSTS(1)
+#define GRXSTSR_OUT_DATA GRXSTSR_PKTSTS(2)
+#define GRXSTSR_OUT_COMP GRXSTSR_PKTSTS(3)
+#define GRXSTSR_SETUP_COMP GRXSTSR_PKTSTS(4)
+#define GRXSTSR_SETUP_DATA GRXSTSR_PKTSTS(6)
+#define GRXSTSR_DPID_MASK (3U<<15) /**< Data PID mask. */
+#define GRXSTSR_DPID(n) ((n)<<15) /**< Data PID value. */
+#define GRXSTSR_BCNT_MASK (0x7FF<<4) /**< Byte count mask. */
+#define GRXSTSR_BCNT(n) ((n)<<4) /**< Byte count value. */
+#define GRXSTSR_CHNUM_MASK (15U<<0) /**< Channel number mask. */
+#define GRXSTSR_CHNUM(n) ((n)<<0) /**< Channel number value. */
+#define GRXSTSR_EPNUM_MASK (15U<<0) /**< Endpoint number mask. */
+#define GRXSTSR_EPNUM(n) ((n)<<0) /**< Endpoint number value. */
+/** @} */
+
+/**
+ * @name GRXSTSP register bit definitions
+ * @{
+ */
+#define GRXSTSP_PKTSTS_MASK (15<<17) /**< Packet status mask. */
+#define GRXSTSP_PKTSTS(n) ((n)<<17) /**< Packet status value. */
+#define GRXSTSP_OUT_GLOBAL_NAK GRXSTSP_PKTSTS(1)
+#define GRXSTSP_OUT_DATA GRXSTSP_PKTSTS(2)
+#define GRXSTSP_OUT_COMP GRXSTSP_PKTSTS(3)
+#define GRXSTSP_SETUP_COMP GRXSTSP_PKTSTS(4)
+#define GRXSTSP_SETUP_DATA GRXSTSP_PKTSTS(6)
+#define GRXSTSP_DPID_MASK (3U<<15) /**< Data PID mask. */
+#define GRXSTSP_DPID(n) ((n)<<15) /**< Data PID value. */
+#define GRXSTSP_BCNT_MASK (0x7FF<<4) /**< Byte count mask. */
+#define GRXSTSP_BCNT_OFF 4 /**< Byte count offset. */
+#define GRXSTSP_BCNT(n) ((n)<<4) /**< Byte count value. */
+#define GRXSTSP_CHNUM_MASK (15U<<0) /**< Channel number mask. */
+#define GRXSTSP_CHNUM(n) ((n)<<0) /**< Channel number value. */
+#define GRXSTSP_EPNUM_MASK (15U<<0) /**< Endpoint number mask. */
+#define GRXSTSP_EPNUM_OFF 0 /**< Endpoint number offset. */
+#define GRXSTSP_EPNUM(n) ((n)<<0) /**< Endpoint number value. */
+/** @} */
+
+/**
+ * @name GRXFSIZ register bit definitions
+ * @{
+ */
+#define GRXFSIZ_RXFD_MASK (0xFFFF<<0) /**< RxFIFO depth mask. */
+#define GRXFSIZ_RXFD(n) ((n)<<0) /**< RxFIFO depth value. */
+/** @} */
+
+/**
+ * @name DIEPTXFx register bit definitions
+ * @{
+ */
+#define DIEPTXF_INEPTXFD_MASK (0xFFFFU<<16)/**< IN endpoint TxFIFO depth
+ mask. */
+#define DIEPTXF_INEPTXFD(n) ((n)<<16) /**< IN endpoint TxFIFO depth
+ value. */
+#define DIEPTXF_INEPTXSA_MASK (0xFFFF<<0) /**< IN endpoint FIFOx transmit
+ RAM start address mask. */
+#define DIEPTXF_INEPTXSA(n) ((n)<<0) /**< IN endpoint FIFOx transmit
+ RAM start address value. */
+/** @} */
+
+/**
+ * @name GCCFG register bit definitions
+ * @{
+ */
+#define GCCFG_SOFOUTEN (1U<<20) /**< SOF output enable. */
+#define GCCFG_VBUSBSEN (1U<<19) /**< Enable the VBUS sensing "B"
+ device. */
+#define GCCFG_VBUSASEN (1U<<18) /**< Enable the VBUS sensing "A"
+ device. */
+#define GCCFG_PWRDWN (1U<<16) /**< Power down. */
+/** @} */
+
+/**
+ * @name HPTXFSIZ register bit definitions
+ * @{
+ */
+#define HPTXFSIZ_PTXFD_MASK (0xFFFFU<<16)/**< Host periodic TxFIFO
+ depth mask. */
+#define HPTXFSIZ_PTXFD(n) ((n)<<16) /**< Host periodic TxFIFO
+ depth value. */
+#define HPTXFSIZ_PTXSA_MASK (0xFFFFU<<0)/**< Host periodic TxFIFO
+ Start address mask. */
+#define HPTXFSIZ_PTXSA(n) ((n)<<0) /**< Host periodic TxFIFO
+ start address value. */
+/** @} */
+
+/**
+ * @name HCFG register bit definitions
+ * @{
+ */
+#define HCFG_FSLSS (1U<<2) /**< FS- and LS-only support. */
+#define HCFG_FSLSPCS_MASK (3U<<0) /**< FS/LS PHY clock select
+ mask. */
+#define HCFG_FSLSPCS_48 (1U<<0) /**< PHY clock is running at
+ 48 MHz. */
+#define HCFG_FSLSPCS_6 (2U<<0) /**< PHY clock is running at
+ 6 MHz. */
+/** @} */
+
+/**
+ * @name HFIR register bit definitions
+ * @{
+ */
+#define HFIR_FRIVL_MASK (0xFFFFU<<0)/**< Frame interval mask. */
+#define HFIR_FRIVL(n) ((n)<<0) /**< Frame interval value. */
+/** @} */
+
+/**
+ * @name HFNUM register bit definitions
+ * @{
+ */
+#define HFNUM_FTREM_MASK (0xFFFFU<<16)/**< Frame time Remaining mask.*/
+#define HFNUM_FTREM(n) ((n)<<16) /**< Frame time Remaining value.*/
+#define HFNUM_FRNUM_MASK (0xFFFFU<<0)/**< Frame number mask. */
+#define HFNUM_FRNUM(n) ((n)<<0) /**< Frame number value. */
+/** @} */
+
+/**
+ * @name HPTXSTS register bit definitions
+ * @{
+ */
+#define HPTXSTS_PTXQTOP_MASK (0xFFU<<24) /**< Top of the periodic
+ transmit request queue
+ mask. */
+#define HPTXSTS_PTXQTOP(n) ((n)<<24) /**< Top of the periodic
+ transmit request queue
+ value. */
+#define HPTXSTS_PTXQSAV_MASK (0xFF<<16) /**< Periodic transmit request
+ queue Space Available
+ mask. */
+#define HPTXSTS_PTXQSAV(n) ((n)<<16) /**< Periodic transmit request
+ queue Space Available
+ value. */
+#define HPTXSTS_PTXFSAVL_MASK (0xFFFF<<0) /**< Periodic transmit Data
+ FIFO Space Available
+ mask. */
+#define HPTXSTS_PTXFSAVL(n) ((n)<<0) /**< Periodic transmit Data
+ FIFO Space Available
+ value. */
+/** @} */
+
+/**
+ * @name HAINT register bit definitions
+ * @{
+ */
+#define HAINT_HAINT_MASK (0xFFFFU<<0)/**< Channel interrupts mask. */
+#define HAINT_HAINT(n) ((n)<<0) /**< Channel interrupts value. */
+/** @} */
+
+/**
+ * @name HAINTMSK register bit definitions
+ * @{
+ */
+#define HAINTMSK_HAINTM_MASK (0xFFFFU<<0)/**< Channel interrupt mask
+ mask. */
+#define HAINTMSK_HAINTM(n) ((n)<<0) /**< Channel interrupt mask
+ value. */
+/** @} */
+
+/**
+ * @name HPRT register bit definitions
+ * @{
+ */
+#define HPRT_PSPD_MASK (3U<<17) /**< Port speed mask. */
+#define HPRT_PSPD_FS (1U<<17) /**< Full speed value. */
+#define HPRT_PSPD_LS (2U<<17) /**< Low speed value. */
+#define HPRT_PTCTL_MASK (15<<13) /**< Port Test control mask. */
+#define HPRT_PTCTL(n) ((n)<<13) /**< Port Test control value. */
+#define HPRT_PPWR (1U<<12) /**< Port power. */
+#define HPRT_PLSTS_MASK (3U<<11) /**< Port Line status mask. */
+#define HPRT_PLSTS_DM (1U<<11) /**< Logic level of D-. */
+#define HPRT_PLSTS_DP (1U<<10) /**< Logic level of D+. */
+#define HPRT_PRST (1U<<8) /**< Port reset. */
+#define HPRT_PSUSP (1U<<7) /**< Port suspend. */
+#define HPRT_PRES (1U<<6) /**< Port Resume. */
+#define HPRT_POCCHNG (1U<<5) /**< Port overcurrent change. */
+#define HPRT_POCA (1U<<4) /**< Port overcurrent active. */
+#define HPRT_PENCHNG (1U<<3) /**< Port enable/disable change.*/
+#define HPRT_PENA (1U<<2) /**< Port enable. */
+#define HPRT_PCDET (1U<<1) /**< Port Connect detected. */
+#define HPRT_PCSTS (1U<<0) /**< Port connect status. */
+/** @} */
+
+/**
+ * @name HCCHAR register bit definitions
+ * @{
+ */
+#define HCCHAR_CHENA (1U<<31) /**< Channel enable. */
+#define HCCHAR_CHDIS (1U<<30) /**< Channel Disable. */
+#define HCCHAR_ODDFRM (1U<<29) /**< Odd frame. */
+#define HCCHAR_DAD_MASK (0x7FU<<22) /**< Device Address mask. */
+#define HCCHAR_DAD(n) ((n)<<22) /**< Device Address value. */
+#define HCCHAR_MCNT_MASK (3U<<20) /**< Multicount mask. */
+#define HCCHAR_MCNT(n) ((n)<<20) /**< Multicount value. */
+#define HCCHAR_EPTYP_MASK (3U<<18) /**< Endpoint type mask. */
+#define HCCHAR_EPTYP(n) ((n)<<18) /**< Endpoint type value. */
+#define HCCHAR_EPTYP_CTL (0U<<18) /**< Control endpoint value. */
+#define HCCHAR_EPTYP_ISO (1U<<18) /**< Isochronous endpoint value.*/
+#define HCCHAR_EPTYP_BULK (2U<<18) /**< Bulk endpoint value. */
+#define HCCHAR_EPTYP_INTR (3U<<18) /**< Interrupt endpoint value. */
+#define HCCHAR_LSDEV (1U<<17) /**< Low-Speed device. */
+#define HCCHAR_EPDIR (1U<<15) /**< Endpoint direction. */
+#define HCCHAR_EPNUM_MASK (15U<<11) /**< Endpoint number mask. */
+#define HCCHAR_EPNUM(n) ((n)<<11) /**< Endpoint number value. */
+#define HCCHAR_MPS_MASK (11U<<0) /**< Maximum packet size mask. */
+#define HCCHAR_MPS(n) (11U<<0) /**< Maximum packet size value. */
+/** @} */
+
+/**
+ * @name HCINT register bit definitions
+ * @{
+ */
+#define HCINT_DTERR (1U<<10) /**< Data toggle error. */
+#define HCINT_FRMOR (1U<<9) /**< Frame overrun. */
+#define HCINT_BBERR (1U<<8) /**< Babble error. */
+#define HCINT_TRERR (1U<<7) /**< Transaction Error. */
+#define HCINT_ACK (1U<<5) /**< ACK response
+ received/transmitted
+ interrupt. */
+#define HCINT_NAK (1U<<4) /**< NAK response received
+ interrupt. */
+#define HCINT_STALL (1U<<3) /**< STALL response received
+ interrupt. */
+#define HCINT_CHH (1U<<1) /**< Channel halted. */
+#define HCINT_XFRC (1U<<0) /**< Transfer completed. */
+/** @} */
+
+/**
+ * @name HCINTMSK register bit definitions
+ * @{
+ */
+#define HCINTMSK_DTERRM (1U<<10) /**< Data toggle error mask. */
+#define HCINTMSK_FRMORM (1U<<9) /**< Frame overrun mask. */
+#define HCINTMSK_BBERRM (1U<<8) /**< Babble error mask. */
+#define HCINTMSK_TRERRM (1U<<7) /**< Transaction error mask. */
+#define HCINTMSK_NYET (1U<<6) /**< NYET response received
+ interrupt mask. */
+#define HCINTMSK_ACKM (1U<<5) /**< ACK Response
+ received/transmitted
+ interrupt mask. */
+#define HCINTMSK_NAKM (1U<<4) /**< NAK response received
+ interrupt mask. */
+#define HCINTMSK_STALLM (1U<<3) /**< STALL response received
+ interrupt mask. */
+#define HCINTMSK_CHHM (1U<<1) /**< Channel halted mask. */
+#define HCINTMSK_XFRCM (1U<<0) /**< Transfer completed mask. */
+/** @} */
+
+/**
+ * @name HCTSIZ register bit definitions
+ * @{
+ */
+#define HCTSIZ_DPID_MASK (3U<<29) /**< PID mask. */
+#define HCTSIZ_DPID_DATA0 (0U<<29) /**< DATA0. */
+#define HCTSIZ_DPID_DATA2 (1U<<29) /**< DATA2. */
+#define HCTSIZ_DPID_DATA1 (2U<<29) /**< DATA1. */
+#define HCTSIZ_DPID_MDATA (3U<<29) /**< MDATA. */
+#define HCTSIZ_PKTCNT_MASK (0x3FFU<<19)/**< Packet count mask. */
+#define HCTSIZ_PKTCNT(n) ((n)<<19) /**< Packet count value. */
+#define HCTSIZ_XFRSIZ_MASK (0x7FFFF<<0)/**< Transfer size mask. */
+#define HCTSIZ_XFRSIZ(n) ((n)<<0) /**< Transfer size value. */
+/** @} */
+
+/**
+ * @name DCFG register bit definitions
+ * @{
+ */
+#define DCFG_PFIVL_MASK (3U<<11) /**< Periodic frame interval
+ mask. */
+#define DCFG_PFIVL(n) ((n)<<11) /**< Periodic frame interval
+ value. */
+#define DCFG_DAD_MASK (0x7FU<<4) /**< Device address mask. */
+#define DCFG_DAD(n) ((n)<<4) /**< Device address value. */
+#define DCFG_NZLSOHSK (1U<<2) /**< Non-Zero-Length status
+ OUT handshake. */
+#define DCFG_DSPD_MASK (3U<<0) /**< Device speed mask. */
+#define DCFG_DSPD_FS11 (3U<<0) /**< Full speed (USB 1.1
+ transceiver clock is 48
+ MHz). */
+/** @} */
+
+/**
+ * @name DCTL register bit definitions
+ * @{
+ */
+#define DCTL_POPRGDNE (1U<<11) /**< Power-on programming done. */
+#define DCTL_CGONAK (1U<<10) /**< Clear global OUT NAK. */
+#define DCTL_SGONAK (1U<<9) /**< Set global OUT NAK. */
+#define DCTL_CGINAK (1U<<8) /**< Clear global non-periodic
+ IN NAK. */
+#define DCTL_SGINAK (1U<<7) /**< Set global non-periodic
+ IN NAK. */
+#define DCTL_TCTL_MASK (7U<<4) /**< Test control mask. */
+#define DCTL_TCTL(n) ((n)<<4 /**< Test control value. */
+#define DCTL_GONSTS (1U<<3) /**< Global OUT NAK status. */
+#define DCTL_GINSTS (1U<<2) /**< Global non-periodic IN
+ NAK status. */
+#define DCTL_SDIS (1U<<1) /**< Soft disconnect. */
+#define DCTL_RWUSIG (1U<<0) /**< Remote wakeup signaling. */
+/** @} */
+
+/**
+ * @name DSTS register bit definitions
+ * @{
+ */
+#define DSTS_FNSOF_MASK (0x3FFU<<8) /**< Frame number of the received
+ SOF mask. */
+#define DSTS_FNSOF(n) ((n)<<8) /**< Frame number of the received
+ SOF value. */
+#define DSTS_EERR (1U<<3) /**< Erratic error. */
+#define DSTS_ENUMSPD_MASK (3U<<1) /**< Enumerated speed mask. */
+#define DSTS_ENUMSPD_FS_48 (3U<<1) /**< Full speed (PHY clock is
+ running at 48 MHz). */
+#define DSTS_SUSPSTS (1U<<0) /**< Suspend status. */
+/** @} */
+
+/**
+ * @name DIEPMSK register bit definitions
+ * @{
+ */
+#define DIEPMSK_TXFEM (1U<<6) /**< Transmit FIFO empty mask. */
+#define DIEPMSK_INEPNEM (1U<<6) /**< IN endpoint NAK effective
+ mask. */
+#define DIEPMSK_ITTXFEMSK (1U<<4) /**< IN token received when
+ TxFIFO empty mask. */
+#define DIEPMSK_TOCM (1U<<3) /**< Timeout condition mask. */
+#define DIEPMSK_EPDM (1U<<1) /**< Endpoint disabled
+ interrupt mask. */
+#define DIEPMSK_XFRCM (1U<<0) /**< Transfer completed
+ interrupt mask. */
+/** @} */
+
+/**
+ * @name DOEPMSK register bit definitions
+ * @{
+ */
+#define DOEPMSK_OTEPDM (1U<<4) /**< OUT token received when
+ endpoint disabled mask. */
+#define DOEPMSK_STUPM (1U<<3) /**< SETUP phase done mask. */
+#define DOEPMSK_EPDM (1U<<1) /**< Endpoint disabled
+ interrupt mask. */
+#define DOEPMSK_XFRCM (1U<<0) /**< Transfer completed
+ interrupt mask. */
+/** @} */
+
+/**
+ * @name DAINT register bit definitions
+ * @{
+ */
+#define DAINT_OEPINT_MASK (0xFFFFU<<16)/**< OUT endpoint interrupt
+ bits mask. */
+#define DAINT_OEPINT(n) ((n)<<16) /**< OUT endpoint interrupt
+ bits value. */
+#define DAINT_IEPINT_MASK (0xFFFFU<<0)/**< IN endpoint interrupt
+ bits mask. */
+#define DAINT_IEPINT(n) ((n)<<0) /**< IN endpoint interrupt
+ bits value. */
+/** @} */
+
+/**
+ * @name DAINTMSK register bit definitions
+ * @{
+ */
+#define DAINTMSK_OEPM_MASK (0xFFFFU<<16)/**< OUT EP interrupt mask
+ bits mask. */
+#define DAINTMSK_OEPM(n) (1U<<(16+(n)))/**< OUT EP interrupt mask
+ bits value. */
+#define DAINTMSK_IEPM_MASK (0xFFFFU<<0)/**< IN EP interrupt mask
+ bits mask. */
+#define DAINTMSK_IEPM(n) (1U<<(n)) /**< IN EP interrupt mask
+ bits value. */
+/** @} */
+
+/**
+ * @name DVBUSDIS register bit definitions
+ * @{
+ */
+#define DVBUSDIS_VBUSDT_MASK (0xFFFFU<<0)/**< Device VBUS discharge
+ time mask. */
+#define DVBUSDIS_VBUSDT(n) ((n)<<0) /**< Device VBUS discharge
+ time value. */
+/** @} */
+
+/**
+ * @name DVBUSPULSE register bit definitions
+ * @{
+ */
+#define DVBUSPULSE_DVBUSP_MASK (0xFFFU<<0) /**< Device VBUSpulsing time
+ mask. */
+#define DVBUSPULSE_DVBUSP(n) ((n)<<0) /**< Device VBUS pulsing time
+ value. */
+/** @} */
+
+/**
+ * @name DIEPEMPMSK register bit definitions
+ * @{
+ */
+#define DIEPEMPMSK_INEPTXFEM(n) (1U<<(n)) /**< IN EP Tx FIFO empty
+ interrupt mask bit. */
+/** @} */
+
+/**
+ * @name DIEPCTL register bit definitions
+ * @{
+ */
+#define DIEPCTL_EPENA (1U<<31) /**< Endpoint enable. */
+#define DIEPCTL_EPDIS (1U<<30) /**< Endpoint disable. */
+#define DIEPCTL_SD1PID (1U<<29) /**< Set DATA1 PID. */
+#define DIEPCTL_SODDFRM (1U<<29) /**< Set odd frame. */
+#define DIEPCTL_SD0PID (1U<<28) /**< Set DATA0 PID. */
+#define DIEPCTL_SEVNFRM (1U<<28) /**< Set even frame. */
+#define DIEPCTL_SNAK (1U<<27) /**< Set NAK. */
+#define DIEPCTL_CNAK (1U<<26) /**< Clear NAK. */
+#define DIEPCTL_TXFNUM_MASK (15U<<22) /**< TxFIFO number mask. */
+#define DIEPCTL_TXFNUM(n) ((n)<<22) /**< TxFIFO number value. */
+#define DIEPCTL_STALL (1U<<21) /**< STALL handshake. */
+#define DIEPCTL_SNPM (1U<<20) /**< Snoop mode. */
+#define DIEPCTL_EPTYP_MASK (3<<18) /**< Endpoint type mask. */
+#define DIEPCTL_EPTYP_CTRL (0U<<18) /**< Control. */
+#define DIEPCTL_EPTYP_ISO (1U<<18) /**< Isochronous. */
+#define DIEPCTL_EPTYP_BULK (2U<<18) /**< Bulk. */
+#define DIEPCTL_EPTYP_INTR (3U<<18) /**< Interrupt. */
+#define DIEPCTL_NAKSTS (1U<<17) /**< NAK status. */
+#define DIEPCTL_EONUM (1U<<16) /**< Even/odd frame. */
+#define DIEPCTL_DPID (1U<<16) /**< Endpoint data PID. */
+#define DIEPCTL_USBAEP (1U<<15) /**< USB active endpoint. */
+#define DIEPCTL_MPSIZ_MASK (0x3FFU<<0) /**< Maximum Packet size mask. */
+#define DIEPCTL_MPSIZ(n) ((n)<<0) /**< Maximum Packet size value. */
+/** @} */
+
+/**
+ * @name DIEPINT register bit definitions
+ * @{
+ */
+#define DIEPINT_TXFE (1U<<7) /**< Transmit FIFO empty. */
+#define DIEPINT_INEPNE (1U<<6) /**< IN endpoint NAK effective. */
+#define DIEPINT_ITTXFE (1U<<4) /**< IN Token received when
+ TxFIFO is empty. */
+#define DIEPINT_TOC (1U<<3) /**< Timeout condition. */
+#define DIEPINT_EPDISD (1U<<1) /**< Endpoint disabled
+ interrupt. */
+#define DIEPINT_XFRC (1U<<0) /**< Transfer completed. */
+/** @} */
+
+/**
+ * @name DIEPTSIZ register bit definitions
+ * @{
+ */
+#define DIEPTSIZ_MCNT_MASK (3U<<29) /**< Multi count mask. */
+#define DIEPTSIZ_MCNT(n) ((n)<<29) /**< Multi count value. */
+#define DIEPTSIZ_PKTCNT_MASK (0x3FF<<19) /**< Packet count mask. */
+#define DIEPTSIZ_PKTCNT(n) ((n)<<19) /**< Packet count value. */
+#define DIEPTSIZ_XFRSIZ_MASK (0x7FFFFU<<0)/**< Transfer size mask. */
+#define DIEPTSIZ_XFRSIZ(n) ((n)<<0) /**< Transfer size value. */
+/** @} */
+
+/**
+ * @name DOEPCTL register bit definitions.
+ * @{
+ */
+#define DOEPCTL_EPENA (1U<<31) /**< Endpoint enable. */
+#define DOEPCTL_EPDIS (1U<<30) /**< Endpoint disable. */
+#define DOEPCTL_SD1PID (1U<<29) /**< Set DATA1 PID. */
+#define DOEPCTL_SODDFRM (1U<<29) /**< Set odd frame. */
+#define DOEPCTL_SD0PID (1U<<28) /**< Set DATA0 PID. */
+#define DOEPCTL_SEVNFRM (1U<<28) /**< Set even frame. */
+#define DOEPCTL_SNAK (1U<<27) /**< Set NAK. */
+#define DOEPCTL_CNAK (1U<<26) /**< Clear NAK. */
+#define DOEPCTL_STALL (1U<<21) /**< STALL handshake. */
+#define DOEPCTL_SNPM (1U<<20) /**< Snoop mode. */
+#define DOEPCTL_EPTYP_MASK (3U<<18) /**< Endpoint type mask. */
+#define DOEPCTL_EPTYP_CTRL (0U<<18) /**< Control. */
+#define DOEPCTL_EPTYP_ISO (1U<<18) /**< Isochronous. */
+#define DOEPCTL_EPTYP_BULK (2U<<18) /**< Bulk. */
+#define DOEPCTL_EPTYP_INTR (3U<<18) /**< Interrupt. */
+#define DOEPCTL_NAKSTS (1U<<17) /**< NAK status. */
+#define DOEPCTL_EONUM (1U<<16) /**< Even/odd frame. */
+#define DOEPCTL_DPID (1U<<16) /**< Endpoint data PID. */
+#define DOEPCTL_USBAEP (1U<<15) /**< USB active endpoint. */
+#define DOEPCTL_MPSIZ_MASK (0x3FFU<<0) /**< Maximum Packet size mask. */
+#define DOEPCTL_MPSIZ(n) ((n)<<0) /**< Maximum Packet size value. */
+/** @} */
+
+/**
+ * @name DOEPINT register bit definitions
+ * @{
+ */
+#define DOEPINT_B2BSTUP (1U<<6) /**< Back-to-back SETUP packets
+ received. */
+#define DOEPINT_OTEPDIS (1U<<4) /**< OUT token received when
+ endpoint disabled. */
+#define DOEPINT_STUP (1U<<3) /**< SETUP phase done. */
+#define DOEPINT_EPDISD (1U<<1) /**< Endpoint disabled
+ interrupt. */
+#define DOEPINT_XFRC (1U<<0) /**< Transfer completed
+ interrupt. */
+/** @} */
+
+/**
+ * @name DOEPTSIZ register bit definitions
+ * @{
+ */
+#define DOEPTSIZ_RXDPID_MASK (3U<<29) /**< Received data PID mask. */
+#define DOEPTSIZ_RXDPID(n) ((n)<<29) /**< Received data PID value. */
+#define DOEPTSIZ_PKTCNT_MASK (0x3FFU<<19)/**< Packet count mask. */
+#define DOEPTSIZ_PKTCNT(n) ((n)<<19) /**< Packet count value. */
+#define DOEPTSIZ_XFRSIZ_MASK (0x7FFFFU<<0)/**< Transfer size mask. */
+#define DOEPTSIZ_XFRSIZ(n) ((n)<<0) /**< Transfer size value. */
+/** @} */
+
+/**
+ * @name PCGCCTL register bit definitions
+ * @{
+ */
+#define PCGCCTL_PHYSUSP (1U<<4) /**< PHY Suspended. */
+#define PCGCCTL_GATEHCLK (1U<<1) /**< Gate HCLK. */
+#define PCGCCTL_STPPCLK (1U<<0) /**< Stop PCLK. */
+/** @} */
+
+/**
+ * @brief OTG registers block memory address.
+ */
+#define OTG_ADDR 0x50000000
+
+/**
+ * @brief Accesses to the OTG registers block.
+ */
+#define OTG ((stm32_otg_t *)OTG_ADDR)
+
+/**
+ * @brief Returns a FIFO address.
+ */
+#define OTG_FIFO(n) ((volatile uint32_t *)(OTG_ADDR + \
+ 0x1000 + \
+ (0x1000 * (n))))
+
+#endif /* _STM32_OTG_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/OTGv1/usb_lld.c b/os/hal/platforms/STM32/OTGv1/usb_lld.c
new file mode 100644
index 000000000..009d9712c
--- /dev/null
+++ b/os/hal/platforms/STM32/OTGv1/usb_lld.c
@@ -0,0 +1,899 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file STM32/OTGv1/usb_lld.c
+ * @brief STM32 USB subsystem low level driver source.
+ *
+ * @addtogroup USB
+ * @{
+ */
+
+#include <string.h>
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_USB || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define TRDT_VALUE 5
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief OTG1 driver identifier.*/
+#if STM32_USB_USE_OTG1 || defined(__DOXYGEN__)
+USBDriver USBD1;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/**
+ * @brief EP0 state.
+ * @note It is an union because IN and OUT endpoints are never used at the
+ * same time for EP0.
+ */
+static union {
+ /**
+ * @brief IN EP0 state.
+ */
+ USBInEndpointState in;
+ /**
+ * @brief OUT EP0 state.
+ */
+ USBOutEndpointState out;
+} ep0_state;
+
+/**
+ * @brief Buffer for the EP0 setup packets.
+ */
+static uint8_t ep8setup_buffer[8];
+
+/**
+ * @brief EP0 initialization structure.
+ */
+static const USBEndpointConfig ep0config = {
+ USB_EP_MODE_TYPE_CTRL | USB_EP_MODE_TRANSACTION,
+ _usb_ep0setup,
+ _usb_ep0in,
+ _usb_ep0out,
+ 0x40,
+ 0x40,
+ &ep0_state.in,
+ &ep0_state.out,
+ ep8setup_buffer
+};
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+static void otg_core_reset(void) {
+
+ /* Wait AHB idle condition.*/
+ while ((OTG->GRSTCTL & GRSTCTL_AHBIDL) == 0)
+ ;
+ /* Core reset and delay of at least 3 PHY cycles.*/
+ OTG->GRSTCTL = GRSTCTL_CSRST;
+ while ((OTG->GRSTCTL & GRSTCTL_CSRST) != 0)
+ ;
+ halPolledDelay(12);
+}
+
+static void otg_disable_ep(void) {
+ unsigned i;
+
+ for (i = 0; i <= USB_MAX_ENDPOINTS; i++) {
+ /* Disable only if enabled because this sentence in the manual:
+ "The application must set this bit only if Endpoint Enable is
+ already set for this endpoint".*/
+ if ((OTG->ie[i].DIEPCTL & DIEPCTL_EPENA) != 0) {
+ OTG->ie[i].DIEPCTL = DIEPCTL_EPDIS;
+ /* Wait for endpoint disable.*/
+ while (!(OTG->ie[i].DIEPINT & DIEPINT_EPDISD))
+ ;
+ }
+ else
+ OTG->ie[i].DIEPCTL = 0;
+ OTG->ie[i].DIEPTSIZ = 0;
+ OTG->ie[i].DIEPINT = 0xFFFFFFFF;
+ /* Disable only if enabled because this sentence in the manual:
+ "The application must set this bit only if Endpoint Enable is
+ already set for this endpoint".
+ Note that the attempt to disable the OUT EP0 is ignored by the
+ hardware but the code is simpler this way.*/
+ if ((OTG->oe[i].DOEPCTL & DOEPCTL_EPENA) != 0) {
+ OTG->oe[i].DOEPCTL = DOEPCTL_EPDIS;
+ /* Wait for endpoint disable.*/
+ while (!(OTG->oe[i].DOEPINT & DOEPINT_OTEPDIS))
+ ;
+ }
+ else
+ OTG->oe[i].DOEPCTL = 0;
+ OTG->oe[i].DOEPTSIZ = 0;
+ OTG->oe[i].DOEPINT = 0xFFFFFFFF;
+ }
+}
+
+static void otg_rxfifo_flush(void) {
+
+ OTG->GRSTCTL = GRSTCTL_RXFFLSH;
+ while ((OTG->GRSTCTL & GRSTCTL_RXFFLSH) != 0)
+ ;
+}
+
+static void otg_txfifo_flush(uint32_t fifo) {
+
+ OTG->GRSTCTL = GRSTCTL_TXFNUM(fifo) | GRSTCTL_TXFFLSH;
+ while ((OTG->GRSTCTL & GRSTCTL_TXFFLSH) != 0)
+ ;
+}
+
+/**
+ * @brief Resets the FIFO RAM memory allocator.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+static void otg_ram_reset(USBDriver *usbp) {
+
+ usbp->pmnext = STM32_USB_OTG1_RX_FIFO_SIZE / 4;
+}
+
+/**
+ * @brief Allocates a block from the FIFO RAM memory.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] size size of the packet buffer to allocate in words
+ *
+ * @notapi
+ */
+static uint32_t otg_ram_alloc(USBDriver *usbp, size_t size) {
+ uint32_t next;
+
+ next = usbp->pmnext;
+ usbp->pmnext += size;
+ chDbgAssert(usbp->pmnext <= STM32_OTG_FIFO_MEM_SIZE,
+ "otg_fifo_alloc(), #1", "FIFO memory overflow");
+ return next;
+}
+
+/**
+ * @brief Writes to a TX FIFO.
+ *
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to copy the endpoint data
+ * @param[in] n maximum number of bytes to copy
+ * @return the number of bytes that were effectively written
+ *
+ * @notapi
+ */
+static void otg_fifo_write(usbep_t ep, const uint8_t *buf, size_t n) {
+ volatile uint32_t *fifop;
+
+ fifop = OTG_FIFO(ep);
+ n = (n + 3) / 4;
+ while (n) {
+ uint32_t dw = (uint32_t)buf[0] |
+ ((uint32_t)buf[1] << 8) |
+ ((uint32_t)buf[2] << 16) |
+ ((uint32_t)buf[3] << 24);
+ *fifop = dw;
+ n--;
+ buf += 4;
+ }
+}
+
+/**
+ * @brief Reads a packet from the RXFIFO.
+ *
+ * @param[out] buf buffer where to copy the endpoint data
+ * @param[in] n number of bytes to pull from the FIFO
+ * @param[in] max number of bytes to copy into the buffer
+ *
+ * @notapi
+ */
+static void otg_fifo_read(uint8_t *buf, size_t n, size_t max) {
+ volatile uint32_t *fifop;
+
+ fifop = OTG_FIFO(0);
+ n = (n + 3) / 4;
+ max = (max + 3) / 4;
+ while (n) {
+ uint32_t dw = *fifop;
+ if (max) {
+ *buf++ = (uint8_t)dw;
+ *buf++ = (uint8_t)(dw >> 8);
+ *buf++ = (uint8_t)(dw >> 16);
+ *buf++ = (uint8_t)(dw >> 24);
+ max--;
+ }
+ n--;
+ }
+}
+
+/**
+ * @brief Incoming packets handler.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+static void otg_rxfifo_handler(USBDriver *usbp) {
+ uint32_t sts, cnt, ep;
+
+ sts = OTG->GRXSTSP;
+ switch (sts & GRXSTSP_PKTSTS_MASK) {
+ case GRXSTSP_SETUP_COMP:
+ break;
+ case GRXSTSP_SETUP_DATA:
+ cnt = (sts & GRXSTSP_BCNT_MASK) >> GRXSTSP_BCNT_OFF;
+ ep = (sts & GRXSTSP_EPNUM_MASK) >> GRXSTSP_EPNUM_OFF;
+ otg_fifo_read(usbp->epc[ep]->setup_buf, cnt, 8);
+ break;
+ case GRXSTSP_OUT_DATA:
+ cnt = (sts & GRXSTSP_BCNT_MASK) >> GRXSTSP_BCNT_OFF;
+ ep = (sts & GRXSTSP_EPNUM_MASK) >> GRXSTSP_EPNUM_OFF;
+ otg_fifo_read(usbp->epc[ep]->out_state->rxbuf, cnt,
+ usbp->epc[ep]->out_state->rxsize -
+ usbp->epc[ep]->out_state->rxcnt);
+ usbp->epc[ep]->out_state->rxbuf += cnt;
+ usbp->epc[ep]->out_state->rxcnt += cnt;
+ break;
+ case GRXSTSP_OUT_GLOBAL_NAK:
+ case GRXSTSP_OUT_COMP:
+ default:
+ ;
+ }
+}
+
+/**
+ * @brief Outgoing packets handler.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+static void otg_txfifo_handler(USBDriver *usbp, usbep_t ep) {
+ uint32_t n;
+
+ n = usbp->epc[ep]->in_state->txsize - usbp->epc[ep]->in_state->txcnt;
+ if (n > usbp->epc[ep]->in_maxsize)
+ n = usbp->epc[ep]->in_maxsize;
+ OTG->ie[ep].DIEPCTL |= DIEPCTL_EPENA | DIEPCTL_CNAK;
+ otg_fifo_write(ep, usbp->epc[ep]->in_state->txbuf, n);
+ usbp->epc[ep]->in_state->txbuf += n;
+ usbp->epc[ep]->in_state->txcnt += n;
+ if (usbp->epc[ep]->in_state->txcnt >= usbp->epc[ep]->in_state->txsize) {
+ /* Transfer finished.*/
+ OTG->DIEPEMPMSK &= ~DIEPEMPMSK_INEPTXFEM(ep);
+ }
+}
+
+/**
+ * @brief Generic endpoint IN handler.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+static void otg_epin_handler(USBDriver *usbp, usbep_t ep) {
+ uint32_t epint = OTG->ie[ep].DIEPINT;
+
+ if (epint & DIEPINT_TXFE) {
+ /* TX FIFO empty or emptying.*/
+ otg_txfifo_handler(usbp, ep);
+ }
+ if (epint & DIEPINT_XFRC) {
+ /* Transmit transfer complete.*/
+ _usb_isr_invoke_in_cb(usbp, ep);
+ }
+ if (epint & DIEPINT_TOC) {
+ /* Timeouts not handled yet, not sure how to handle.*/
+ }
+ OTG->ie[ep].DIEPINT = 0xFFFFFFFF;
+}
+
+/**
+ * @brief Generic endpoint OUT handler.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+static void otg_epout_handler(USBDriver *usbp, usbep_t ep) {
+ uint32_t epint = OTG->oe[ep].DOEPINT;
+
+ /* Is it a setup packet?*/
+ if (epint & DOEPINT_STUP) {
+ /* Setup packets handling, setup packets are handled using a
+ specific callback.*/
+ _usb_isr_invoke_setup_cb(usbp, ep);
+ }
+ if (epint & DOEPINT_XFRC) {
+ /* Receive transfer complete.*/
+ _usb_isr_invoke_out_cb(usbp, ep);
+ }
+ OTG->oe[ep].DOEPINT = 0xFFFFFFFF;
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_USB_USE_OTG1 || defined(__DOXYGEN__)
+/**
+ * @brief OTG1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(OTG_FS_IRQHandler) {
+ USBDriver *usbp = &USBD1;
+ uint32_t sts;
+
+ CH_IRQ_PROLOGUE();
+
+ sts = OTG->GINTSTS & OTG->GINTMSK;
+
+ /* Reset interrupt handling.*/
+ if (sts & GINTSTS_USBRST) {
+ _usb_reset(usbp);
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_RESET);
+ OTG->GINTSTS = GINTSTS_USBRST;
+ }
+
+ /* Enumeration done.*/
+ if (sts & GINTSTS_ENUMDNE) {
+ (void)OTG->DSTS;
+ OTG->GINTSTS = GINTSTS_ENUMDNE;
+ }
+
+ /* SOF interrupt handling.*/
+ if (sts & GINTSTS_SOF) {
+ _usb_isr_invoke_sof_cb(usbp);
+ OTG->GINTSTS = GINTSTS_SOF;
+ }
+
+ /* RX FIFO not empty handling.*/
+ if (sts & GINTMSK_RXFLVLM) {
+ otg_rxfifo_handler(usbp);
+ }
+
+ /* IN/OUT endpoints event handling, timeout and transfer complete events
+ are handled.*/
+ if (sts & (GINTSTS_IEPINT | GINTSTS_OEPINT)) {
+ uint32_t src = OTG->DAINT;
+ if (src & (1 << 0))
+ otg_epin_handler(usbp, 0);
+ if (src & (1 << 1))
+ otg_epin_handler(usbp, 1);
+ if (src & (1 << 2))
+ otg_epin_handler(usbp, 2);
+ if (src & (1 << 3))
+ otg_epin_handler(usbp, 3);
+ if (src & (1 << 16))
+ otg_epout_handler(usbp, 0);
+ if (src & (1 << 17))
+ otg_epout_handler(usbp, 1);
+ if (src & (1 << 18))
+ otg_epout_handler(usbp, 2);
+ if (src & (1 << 19))
+ otg_epout_handler(usbp, 3);
+ }
+
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level USB driver initialization.
+ *
+ * @notapi
+ */
+void usb_lld_init(void) {
+
+ /* Driver initialization.*/
+ usbObjectInit(&USBD1);
+}
+
+/**
+ * @brief Configures and activates the USB peripheral.
+ * @note Starting the ORG cell can be a slow operation carried out with
+ * interrupts disabled, perform it before starting time-critical
+ * operations.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_start(USBDriver *usbp) {
+
+ if (usbp->state == USB_STOP) {
+ /* Clock activation.*/
+#if STM32_USB_USE_OTG1
+ if (&USBD1 == usbp) {
+ /* OTG FS clock enable and reset.*/
+ rccEnableOTG_FS(FALSE);
+ rccResetOTG_FS();
+
+ /* Enables IRQ vector.*/
+ nvicEnableVector(OTG_FS_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_USB_OTG1_IRQ_PRIORITY));
+ }
+#endif
+
+ /* Soft core reset.*/
+ otg_core_reset();
+
+ /* Internal FS PHY activation.*/
+ OTG->GCCFG = GCCFG_PWRDWN;
+
+ /* - Forced device mode.
+ - USB turn-around time = TRDT_VALUE.
+ - Full Speed 1.1 PHY.*/
+ OTG->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE) | GUSBCFG_PHYSEL;
+
+ /* Interrupt on TXFIFOs empty.*/
+ OTG->GAHBCFG = GAHBCFG_PTXFELVL | GAHBCFG_TXFELVL;
+
+ /* 48MHz 1.1 PHY.*/
+ OTG->DCFG = 0x02200000 | DCFG_PFIVL(0) | DCFG_DSPD_FS11;
+
+ /* PHY enabled.*/
+ OTG->PCGCCTL = 0;
+
+ /* Endpoints re-initialization.*/
+ otg_disable_ep();
+
+ /* Clear all pending Device Interrupts, only the USB Reset interrupt
+ is required initially.*/
+ OTG->DIEPMSK = 0;
+ OTG->DOEPMSK = 0;
+ OTG->DAINTMSK = 0;
+ OTG->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM | /*GINTMSK_USBSUSPM |
+ GINTMSK_ESUSPM |*/ GINTMSK_SOFM;
+ OTG->GINTSTS = 0xFFFFFFFF; /* Clears all pending IRQs, if any. */
+
+ /* Global interrupts enable.*/
+ OTG->GAHBCFG |= GAHBCFG_GINTMSK;
+ }
+}
+
+/**
+ * @brief Deactivates the USB peripheral.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_stop(USBDriver *usbp) {
+
+ /* If in ready state then disables the USB clock.*/
+ if (usbp->state == USB_STOP) {
+#if STM32_USB_USE_USB1
+ if (&USBD1 == usbp) {
+ nvicDisableVector(OTG_FS_IRQn);
+ rccDisableOTG1(FALSE);
+ }
+#endif
+ }
+ OTG->GCCFG = 0;
+}
+
+/**
+ * @brief USB low level reset routine.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_reset(USBDriver *usbp) {
+ unsigned i;
+
+ /* Endpoint interrupts all disabled and cleared.*/
+ OTG->DAINTMSK = 0;
+ OTG->DAINT = 0xFFFFFFFF;
+
+ /* All endpoints in NAK mode, interrupts cleared.*/
+ for (i = 0; i <= USB_MAX_ENDPOINTS; i++) {
+ OTG->ie[i].DIEPCTL = DIEPCTL_SNAK;
+ OTG->oe[i].DOEPCTL = DOEPCTL_SNAK;
+ OTG->ie[i].DIEPINT = 0xFFFFFFFF;
+ OTG->oe[i].DOEPINT = 0xFFFFFFFF;
+ }
+
+ /* Resets the FIFO memory allocator.*/
+ otg_ram_reset(usbp);
+
+ /* Receive FIFO size initialization, the address is always zero.*/
+ OTG->GRXFSIZ = STM32_USB_OTG1_RX_FIFO_SIZE / 4;
+ otg_rxfifo_flush();
+
+ /* Enables also EP-related interrupt sources.*/
+ OTG->GINTMSK |= GINTMSK_RXFLVLM | GINTMSK_OEPM | GINTMSK_IEPM;
+ OTG->DIEPMSK = DIEPMSK_TOCM | DIEPMSK_XFRCM;
+ OTG->DOEPMSK = DOEPMSK_STUPM | DOEPMSK_XFRCM;
+
+ /* EP0 initialization, it is a special case.*/
+ usbp->epc[0] = &ep0config;
+ OTG->oe[0].DOEPTSIZ = 0;
+ OTG->oe[0].DOEPCTL = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_CTRL |
+ DOEPCTL_MPSIZ(ep0config.out_maxsize);
+ OTG->ie[0].DIEPTSIZ = 0;
+ OTG->ie[0].DIEPCTL = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_CTRL |
+ DIEPCTL_TXFNUM(0) | DIEPCTL_MPSIZ(ep0config.in_maxsize);
+ OTG->DIEPTXF0 = DIEPTXF_INEPTXFD(ep0config.in_maxsize / 4) |
+ DIEPTXF_INEPTXSA(otg_ram_alloc(usbp,
+ ep0config.in_maxsize / 4));
+ otg_txfifo_flush(0);
+ OTG->DAINTMSK = DAINTMSK_IEPM(0) | DAINTMSK_IEPM(0);
+}
+
+/**
+ * @brief Sets the USB address.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_set_address(USBDriver *usbp) {
+
+ OTG->DCFG = (OTG->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(usbp->address);
+}
+
+/**
+ * @brief Enables an endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
+ uint32_t ctl, fsize;
+
+ /* IN and OUT common parameters.*/
+ switch (usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) {
+ case USB_EP_MODE_TYPE_CTRL:
+ ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_CTRL;
+ break;
+ case USB_EP_MODE_TYPE_ISOC:
+ ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_ISO;
+ break;
+ case USB_EP_MODE_TYPE_BULK:
+ ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_BULK;
+ break;
+ case USB_EP_MODE_TYPE_INTR:
+ ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_INTR;
+ break;
+ default:
+ return;
+ }
+
+ /* OUT endpoint activation or deactivation.*/
+ OTG->oe[ep].DOEPTSIZ = 0;
+ if (usbp->epc[ep]->out_cb != NULL)
+ OTG->oe[ep].DOEPCTL = ctl | DOEPCTL_MPSIZ(usbp->epc[ep]->out_maxsize);
+ else
+ OTG->oe[ep].DOEPCTL &= ~DOEPCTL_USBAEP;
+
+ /* IN endpoint activation or deactivation.*/
+ OTG->ie[ep].DIEPTSIZ = 0;
+ if (usbp->epc[ep]->in_cb != NULL) {
+ /* FIFO allocation for the IN endpoint.*/
+ fsize = usbp->epc[ep]->in_maxsize / 4;
+ OTG->DIEPTXF[ep - 1] = DIEPTXF_INEPTXFD(fsize) |
+ DIEPTXF_INEPTXSA(otg_ram_alloc(usbp, fsize));
+ otg_txfifo_flush(ep);
+
+ OTG->ie[ep].DIEPCTL = ctl |
+ DIEPCTL_TXFNUM(ep) |
+ DIEPCTL_MPSIZ(usbp->epc[ep]->in_maxsize);
+ }
+ else {
+ OTG->DIEPTXF[ep - 1] = 0x02000400; /* Reset value.*/
+ otg_txfifo_flush(ep);
+ OTG->ie[ep].DIEPCTL &= ~DIEPCTL_USBAEP;
+ }
+}
+
+/**
+ * @brief Disables all the active endpoints except the endpoint zero.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_disable_endpoints(USBDriver *usbp) {
+
+ /* Resets the FIFO memory allocator.*/
+ otg_ram_reset(usbp);
+
+ /* Disabling all endpoints.*/
+ otg_disable_ep();
+}
+
+/**
+ * @brief Returns the status of an OUT endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The endpoint status.
+ * @retval EP_STATUS_DISABLED The endpoint is not active.
+ * @retval EP_STATUS_STALLED The endpoint is stalled.
+ * @retval EP_STATUS_ACTIVE The endpoint is active.
+ *
+ * @notapi
+ */
+usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+ (void)ep;
+
+ return 0;
+}
+
+/**
+ * @brief Returns the status of an IN endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The endpoint status.
+ * @retval EP_STATUS_DISABLED The endpoint is not active.
+ * @retval EP_STATUS_STALLED The endpoint is stalled.
+ * @retval EP_STATUS_ACTIVE The endpoint is active.
+ *
+ * @notapi
+ */
+usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+ (void)ep;
+
+ return 0;
+}
+
+/**
+ * @brief Reads a setup packet from the dedicated packet buffer.
+ * @details This function must be invoked in the context of the @p setup_cb
+ * callback in order to read the received setup packet.
+ * @pre In order to use this function the endpoint must have been
+ * initialized as a control endpoint.
+ * @post The endpoint is ready to accept another packet.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the packet data
+ *
+ * @notapi
+ */
+void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
+
+ memcpy(buf, usbp->epc[ep]->setup_buf, 8);
+}
+
+/**
+ * @brief Reads from a dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @note This function can be invoked both in thread and IRQ context.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the packet data
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ * @return The received packet size regardless the specified
+ * @p n parameter.
+ * @retval 0 Zero size packet received.
+ *
+ * @notapi
+ */
+size_t usb_lld_read_packet_buffer(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+
+ (void)usbp;
+ (void)ep;
+ (void)buf;
+ (void)n;
+
+ return 0;
+}
+
+/**
+ * @brief Writes to a dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @note This function can be invoked both in thread and IRQ context.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the packet data
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ *
+ * @notapi
+ */
+void usb_lld_write_packet_buffer(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+
+ (void)usbp;
+ (void)ep;
+ (void)buf;
+ (void)n;
+}
+
+/**
+ * @brief Prepares for a receive operation.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the received data
+ * @param[in] n maximum number of bytes to copy
+ *
+ * @notapi
+ */
+void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+
+ (void)usbp;
+ (void)ep;
+ (void)buf;
+ (void)n;
+}
+
+/**
+ * @brief Prepares for a transmit operation.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the data to be transmitted
+ * @param[in] n maximum number of bytes to copy
+ *
+ * @notapi
+ */
+void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+ USBInEndpointState *isp = usbp->epc[ep]->in_state;
+
+ isp->txbuf = buf;
+ isp->txsize = n;
+ isp->txcnt = 0;
+
+ if (n == 0) {
+ /* Special case, sending zero size packet.*/
+ OTG->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(1) | DIEPTSIZ_XFRSIZ(0);
+ }
+ else {
+ /* Transfer initialization.*/
+ uint32_t pcnt = (n + (usbp->epc[ep]->in_maxsize - 1) /
+ usbp->epc[ep]->in_maxsize);
+ OTG->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(pcnt) |
+ DIEPTSIZ_XFRSIZ(usbp->epc[ep]->in_state->txsize);
+ }
+ OTG->DIEPEMPMSK |= DIEPEMPMSK_INEPTXFEM(ep);
+}
+
+/**
+ * @brief Starts a receive operation on an OUT endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+ (void)ep;
+}
+
+/**
+ * @brief Starts a transmit operation on an IN endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+ (void)ep;
+}
+
+/**
+ * @brief Brings an OUT endpoint in the stalled state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+
+ OTG->oe[ep].DOEPCTL |= DOEPCTL_STALL;
+}
+
+/**
+ * @brief Brings an IN endpoint in the stalled state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+
+ OTG->ie[ep].DIEPCTL |= DIEPCTL_STALL;
+}
+
+/**
+ * @brief Brings an OUT endpoint in the active state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+
+ OTG->oe[ep].DOEPCTL &= ~DOEPCTL_STALL;
+}
+
+/**
+ * @brief Brings an IN endpoint in the active state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+
+ OTG->ie[ep].DIEPCTL &= ~DIEPCTL_STALL;
+}
+
+#endif /* HAL_USE_USB */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/OTGv1/usb_lld.h b/os/hal/platforms/STM32/OTGv1/usb_lld.h
new file mode 100644
index 000000000..4cc18a05b
--- /dev/null
+++ b/os/hal/platforms/STM32/OTGv1/usb_lld.h
@@ -0,0 +1,402 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file STM32/OTGv1/usb_lld.h
+ * @brief STM32 USB subsystem low level driver header.
+ *
+ * @addtogroup USB
+ * @{
+ */
+
+#ifndef _USB_LLD_H_
+#define _USB_LLD_H_
+
+#if HAL_USE_USB || defined(__DOXYGEN__)
+
+#include "stm32_otg.h"
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Maximum endpoint address.
+ */
+#define USB_MAX_ENDPOINTS 3
+
+/**
+ * @brief The address can be changed immediately upon packet reception.
+ */
+#define USB_SET_ADDRESS_MODE USB_EARLY_SET_ADDRESS
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief OTG1 driver enable switch.
+ * @details If set to @p TRUE the support for USB1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_USB_USE_OTG1) || defined(__DOXYGEN__)
+#define STM32_USB_USE_OTG1 TRUE
+#endif
+
+/**
+ * @brief OTG1 interrupt priority level setting.
+ */
+#if !defined(STM32_USB_OTG1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_USB_OTG1_IRQ_PRIORITY 6
+#endif
+
+/**
+ * @brief OTG1 RX shared FIFO size.
+ * @note Must be a multiple of 4.
+ */
+#if !defined(STM32_USB_OTG1_RX_FIFO_SIZE) || defined(__DOXYGEN__)
+#define STM32_USB_OTG1_RX_FIFO_SIZE 512
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_USB_USE_OTG1 && !STM32_HAS_OTG1
+#error "OTG1 not present in the selected device"
+#endif
+
+#if !STM32_USB_USE_OTG1
+#error "USB driver activated but no USB peripheral assigned"
+#endif
+
+#if (STM32_USB_OTG1_RX_FIFO_SIZE & 3) != 0
+#error "RX FIFO size must be a multiple of 4"
+#endif
+
+#if defined(STM32F4XX) || defined(STM32F2XX)
+#define STM32_USBCLK STM32_PLL48CLK
+#elif defined(STM32F10X_CL)
+#define STM32_USBCLK STM32_OTGFSCLK
+#else
+#error "unsupported STM32 platform for OTG functionality"
+#endif
+
+#if STM32_USBCLK != 48000000
+#error "the USB OTG driver requires a 48MHz clock"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of an endpoint state structure.
+ */
+typedef struct {
+ /**
+ * @brief Pointer to the transmission buffer.
+ */
+ const uint8_t *txbuf;
+ /**
+ * @brief Requested transmit transfer size.
+ */
+ size_t txsize;
+ /**
+ * @brief Transmitted bytes so far.
+ */
+ size_t txcnt;
+} USBInEndpointState;
+
+/**
+ * @brief Type of an endpoint state structure.
+ */
+typedef struct {
+ /**
+ * @brief Number of packets to receive.
+ */
+ uint16_t rxpkts;
+ /**
+ * @brief Pointer to the receive buffer.
+ */
+ uint8_t *rxbuf;
+ /**
+ * @brief Requested receive transfer size.
+ */
+ size_t rxsize;
+ /**
+ * @brief Received bytes so far.
+ */
+ size_t rxcnt;
+} USBOutEndpointState;
+
+/**
+ * @brief Type of an USB endpoint configuration structure.
+ * @note Platform specific restrictions may apply to endpoints.
+ */
+typedef struct {
+ /**
+ * @brief Type and mode of the endpoint.
+ */
+ uint32_t ep_mode;
+ /**
+ * @brief Setup packet notification callback.
+ * @details This callback is invoked when a setup packet has been
+ * received.
+ * @post The application must immediately call @p usbReadPacket() in
+ * order to access the received packet.
+ * @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL
+ * endpoints, it should be set to @p NULL for other endpoint
+ * types.
+ */
+ usbepcallback_t setup_cb;
+ /**
+ * @brief IN endpoint notification callback.
+ * @details This field must be set to @p NULL if the IN endpoint is not
+ * used.
+ */
+ usbepcallback_t in_cb;
+ /**
+ * @brief OUT endpoint notification callback.
+ * @details This field must be set to @p NULL if the OUT endpoint is not
+ * used.
+ */
+ usbepcallback_t out_cb;
+ /**
+ * @brief IN endpoint maximum packet size.
+ * @details This field must be set to zero if the IN endpoint is not
+ * used.
+ */
+ uint16_t in_maxsize;
+ /**
+ * @brief OUT endpoint maximum packet size.
+ * @details This field must be set to zero if the OUT endpoint is not
+ * used.
+ */
+ uint16_t out_maxsize;
+ /**
+ * @brief @p USBEndpointState associated to the IN endpoint.
+ * @details This structure maintains the state of the IN endpoint when
+ * the endpoint is not in packet mode. Endpoints configured in
+ * packet mode must set this field to @p NULL.
+ */
+ USBInEndpointState *in_state;
+ /**
+ * @brief @p USBEndpointState associated to the OUT endpoint.
+ * @details This structure maintains the state of the OUT endpoint when
+ * the endpoint is not in packet mode. Endpoints configured in
+ * packet mode must set this field to @p NULL.
+ */
+ USBOutEndpointState *out_state;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to a buffer for setup packets.
+ * @details Setup packets require a dedicated 8-bytes buffer, set this
+ * field to @p NULL for non-control endpoints.
+ */
+ uint8_t *setup_buf;
+} USBEndpointConfig;
+
+/**
+ * @brief Type of an USB driver configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief USB events callback.
+ * @details This callback is invoked when an USB driver event is registered.
+ */
+ usbeventcb_t event_cb;
+ /**
+ * @brief Device GET_DESCRIPTOR request callback.
+ * @note This callback is mandatory and cannot be set to @p NULL.
+ */
+ usbgetdescriptor_t get_descriptor_cb;
+ /**
+ * @brief Requests hook callback.
+ * @details This hook allows to be notified of standard requests or to
+ * handle non standard requests.
+ */
+ usbreqhandler_t requests_hook_cb;
+ /**
+ * @brief Start Of Frame callback.
+ */
+ usbcallback_t sof_cb;
+ /* End of the mandatory fields.*/
+} USBConfig;
+
+/**
+ * @brief Structure representing an USB driver.
+ */
+struct USBDriver {
+ /**
+ * @brief Driver state.
+ */
+ usbstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const USBConfig *config;
+ /**
+ * @brief Field available to user, it can be used to associate an
+ * application-defined handler to the USB driver.
+ */
+ void *param;
+ /**
+ * @brief Bit map of the transmitting IN endpoints.
+ */
+ uint16_t transmitting;
+ /**
+ * @brief Bit map of the receiving OUT endpoints.
+ */
+ uint16_t receiving;
+ /**
+ * @brief Active endpoints configurations.
+ */
+ const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1];
+ /**
+ * @brief Endpoint 0 state.
+ */
+ usbep0state_t ep0state;
+ /**
+ * @brief Next position in the buffer to be transferred through endpoint 0.
+ */
+ uint8_t *ep0next;
+ /**
+ * @brief Number of bytes yet to be transferred through endpoint 0.
+ */
+ size_t ep0n;
+ /**
+ * @brief Endpoint 0 end transaction callback.
+ */
+ usbcallback_t ep0endcb;
+ /**
+ * @brief Setup packet buffer.
+ */
+ uint8_t setup[8];
+ /**
+ * @brief Current USB device status.
+ */
+ uint16_t status;
+ /**
+ * @brief Assigned USB address.
+ */
+ uint8_t address;
+ /**
+ * @brief Current USB device configuration.
+ */
+ uint8_t configuration;
+#if defined(USB_DRIVER_EXT_FIELDS)
+ USB_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the next address in the packet memory.
+ */
+ uint32_t pmnext;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Fetches a 16 bits word value from an USB message.
+ *
+ * @param[in] p pointer to the 16 bits word
+ *
+ * @notapi
+ */
+#define usb_lld_fetch_word(p) (*(uint16_t *)(p))
+
+/**
+ * @brief Returns the exact size of a receive transaction.
+ * @details The received size can be different from the size specified in
+ * @p usbStartReceiveI() because the last packet could have a size
+ * different from the expected one.
+ * @pre The OUT endpoint must have been configured in transaction mode
+ * in order to use this function.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return Received data size.
+ *
+ * @notapi
+ */
+#define usb_lld_get_transaction_size(usbp, ep) \
+ ((usbp)->epc[ep]->out_state->rxcnt)
+
+/**
+ * @brief Connects the USB device.
+ *
+ * @api
+ */
+#define usb_lld_connect_bus(usbp) (OTG->GCCFG |= GCCFG_VBUSBSEN)
+
+/**
+ * @brief Disconnect the USB device.
+ *
+ * @api
+ */
+#define usb_lld_disconnect_bus(usbp) (OTG->GCCFG &= ~GCCFG_VBUSBSEN)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_USB_USE_OTG1 && !defined(__DOXYGEN__)
+extern USBDriver USBD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void usb_lld_init(void);
+ void usb_lld_start(USBDriver *usbp);
+ void usb_lld_stop(USBDriver *usbp);
+ void usb_lld_reset(USBDriver *usbp);
+ void usb_lld_set_address(USBDriver *usbp);
+ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep);
+ void usb_lld_disable_endpoints(USBDriver *usbp);
+ usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep);
+ usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf);
+ size_t usb_lld_read_packet_buffer(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ void usb_lld_write_packet_buffer(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
+ void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
+ void usb_lld_start_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_start_in(USBDriver *usbp, usbep_t ep);
+ void usb_lld_stall_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
+ void usb_lld_clear_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_clear_in(USBDriver *usbp, usbep_t ep);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_USB */
+
+#endif /* _USB_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/can_lld.h b/os/hal/platforms/STM32/can_lld.h
index 6ab69efb2..d9bf3bb39 100644
--- a/os/hal/platforms/STM32/can_lld.h
+++ b/os/hal/platforms/STM32/can_lld.h
@@ -188,7 +188,7 @@ typedef struct {
*/
uint32_t mode:1;
/**
- * @brief Filter sclae.
+ * @brief Filter scale.
* @note This bit represent the CAN_FS1R register bit associated to this
* filter (0=16 bits mode, 1=32 bits mode).
*/
diff --git a/os/hal/platforms/STM32/i2s_lld.c b/os/hal/platforms/STM32/i2s_lld.c
new file mode 100644
index 000000000..692988385
--- /dev/null
+++ b/os/hal/platforms/STM32/i2s_lld.c
@@ -0,0 +1,165 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file templates/i2s_lld.c
+ * @brief I2S Driver subsystem low level driver source template.
+ *
+ * @addtogroup I2S
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_I2S || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level I2S driver initialization.
+ *
+ * @notapi
+ */
+void i2s_lld_init(void) {
+
+#if STM32_I2S_USE_I2S2
+ spiObjectInit(&I2SD2);
+ I2SD2.spi = SPI2;
+#endif
+
+#if STM32_I2S_USE_I2S3
+ spiObjectInit(&I2SD3);
+ I2SD3.spi = SPI3;
+#endif
+}
+
+/**
+ * @brief Configures and activates the I2S peripheral.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @notapi
+ */
+void i2s_lld_start(I2SDriver *i2sp) {
+
+ /* If in stopped state then enables the SPI and DMA clocks.*/
+ if (i2sp->state == I2S_STOP) {
+#if STM32_SPI_USE_SPI2
+ if (&SPID2 == spip) {
+ bool_t b;
+ b = dmaStreamAllocate(spip->dma,
+ STM32_I2S_I2S2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
+ (void *)spip);
+ chDbgAssert(!b, "spi_lld_start(), #1", "stream already allocated");
+ rccEnableSPI2(FALSE);
+ }
+#endif
+#if STM32_SPI_USE_SPI3
+ if (&SPID3 == spip) {
+ bool_t b;
+ b = dmaStreamAllocate(spip->dma,
+ STM32_I2S_I2S3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
+ (void *)spip);
+ chDbgAssert(!b, "spi_lld_start(), #2", "stream already allocated");
+ rccEnableSPI3(FALSE);
+ }
+#endif
+ }
+ /* Configuration.*/
+}
+
+/**
+ * @brief Deactivates the I2S peripheral.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @notapi
+ */
+void i2s_lld_stop(I2SDriver *i2sp) {
+
+ if (i2sp->state == I2S_READY) {
+ /* Clock deactivation.*/
+
+ }
+}
+
+/**
+ * @brief Starts a I2S data exchange.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @notapi
+ */
+void i2s_lld_start_exchange(I2SDriver *i2sp) {
+
+}
+
+/**
+ * @brief Starts a I2S data exchange in continuous mode.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @notapi
+ */
+void i2s_lld_start_exchange_continuous(I2SDriver *i2sp) {
+
+}
+
+/**
+ * @brief Stops the ongoing data exchange.
+ * @details The ongoing data exchange, if any, is stopped, if the driver
+ * was not active the function does nothing.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @notapi
+ */
+void i2s_lld_stop_exchange(I2SDriver *i2sp) {
+
+}
+
+#endif /* HAL_USE_I2S */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/i2s_lld.h b/os/hal/platforms/STM32/i2s_lld.h
new file mode 100644
index 000000000..52f00d2b7
--- /dev/null
+++ b/os/hal/platforms/STM32/i2s_lld.h
@@ -0,0 +1,321 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file templates/i2s_lld.h
+ * @brief I2S Driver subsystem low level driver header template.
+ *
+ * @addtogroup I2S
+ * @{
+ */
+
+#ifndef _I2S_LLD_H_
+#define _I2S_LLD_H_
+
+#if HAL_USE_I2S || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief I2S2 driver enable switch.
+ * @details If set to @p TRUE the support for I2S2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_I2S_USE_I2S2) || defined(__DOXYGEN__)
+#define STM32_I2S_USE_I2S2 TRUE
+#endif
+
+/**
+ * @brief I2S3 driver enable switch.
+ * @details If set to @p TRUE the support for I2S3 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_I2S_USE_I2S3) || defined(__DOXYGEN__)
+#define STM32_I2S_USE_I2S3 TRUE
+#endif
+
+/**
+ * @brief I2S2 interrupt priority level setting.
+ */
+#if !defined(STM32_I2S_I2S2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_I2S2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2S3 interrupt priority level setting.
+ */
+#if !defined(STM32_I2S_I2S3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_I2S3_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2S2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_I2S_I2S2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_I2S2_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2S3 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_I2S_I2S2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_I2S2_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2S DMA error hook.
+ */
+#if !defined(STM32_I2S_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_I2S_DMA_ERROR_HOOK(i2sp) chSysHalt()
+#endif
+
+#if STM32_ADVANCED_DMA || defined(__DOXYGEN__)
+
+/**
+ * @brief DMA stream used for I2S2 RX operations.
+ * @note This option is only available on platforms with enhanced DMA.
+ */
+#if !defined(STM32_I2S_I2S2_RX_DMA_STREAM) || defined(__DOXYGEN__)
+#define STM32_I2S_I2S2_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0)
+#endif
+
+/**
+ * @brief DMA stream used for I2S2 TX operations.
+ * @note This option is only available on platforms with enhanced DMA.
+ */
+#if !defined(STM32_I2S_I2S2_TX_DMA_STREAM) || defined(__DOXYGEN__)
+#define STM32_I2S_I2S2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#endif
+
+/**
+ * @brief DMA stream used for I2S3 RX operations.
+ * @note This option is only available on platforms with enhanced DMA.
+ */
+#if !defined(STM32_I2S_I2S3_RX_DMA_STREAM) || defined(__DOXYGEN__)
+#define STM32_I2S_I2S3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
+#endif
+
+/**
+ * @brief DMA stream used for I2S3 TX operations.
+ * @note This option is only available on platforms with enhanced DMA.
+ */
+#if !defined(STM32_I2S_I2S3_TX_DMA_STREAM) || defined(__DOXYGEN__)
+#define STM32_I2S_I2S3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#endif
+
+#else /* !STM32_ADVANCED_DMA */
+
+/* Fixed streams for platforms using the old DMA peripheral, the values are
+ valid for both STM32F1xx and STM32L1xx.*/
+#define STM32_I2S_I2S2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_I2S_I2S2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2S_I2S3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_I2S_I2S3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+
+#endif /* !STM32_ADVANCED_DMA */
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_I2S_USE_I2S2 && !STM32_HAS_SPI2
+#error "SPI2 not present in the selected device"
+#endif
+
+#if STM32_I2S_USE_I2S3 && !STM32_HAS_SPI3
+#error "SPI3 not present in the selected device"
+#endif
+
+#if !STM32_I2S_USE_I2S2 && !STM32_I2S_USE_I2S3
+#error "I2S driver activated but no I2S peripheral assigned"
+#endif
+
+#if STM32_I2S_USE_I2S2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_I2S2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK)
+#error "invalid DMA stream associated to I2S2 RX"
+#endif
+
+#if STM32_I2S_USE_I2S2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_I2S2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK)
+#error "invalid DMA stream associated to I2S2 TX"
+#endif
+
+#if STM32_I2S_USE_I2S3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_I2S3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK)
+#error "invalid DMA stream associated to I2S3 RX"
+#endif
+
+#if STM32_I2S_USE_I2S3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_I2S3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK)
+#error "invalid DMA stream associated to I2S3 TX"
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief I2S mode type.
+ */
+typedef uint32_t i2smode_t;
+
+/**
+ * @brief Type of a structure representing an I2S driver.
+ */
+typedef struct I2SDriver I2SDriver;
+
+/**
+ * @brief I2S notification callback type.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ * @param[in] buffer pointer to the buffer
+ * @param[in] n number of sample positions starting from @p buffer
+ */
+typedef void (*i2scallback_t)(I2SDriver *i2sp, void *buffer, size_t n);
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief I2S mode selection.
+ */
+ i2smode_t mode;
+ /**
+ * @brief Transmission buffer pointer.
+ */
+ const void *tx_buffer;
+ /**
+ * @brief Transmission buffer size in number of samples.
+ */
+ size_t tx_size;
+ /**
+ * @brief Callback function associated to the transmission or @p NULL.
+ */
+ i2scallback_t tx_cb;
+ /**
+ * @brief Receive buffer pointer.
+ */
+ void *rx_buffer;
+ /**
+ * @brief Receive buffer size in number of samples.
+ */
+ size_t rx_size;
+ /**
+ * @brief Callback function associated to the reception or @p NULL.
+ */
+ i2scallback_t rx_cb;;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Configuration of the I2SCFGR register.
+ * @details See the STM32 reference manual, this register is used for
+ * the I2S configuration, the following bits must not be
+ * specified because handled directly by the driver:
+ * - I2SMOD
+ * - I2SE
+ * - I2SCFG
+ * .
+ */
+ int16_t i2scfgr;
+ /**
+ * @brief Configuration of the I2SPR register.
+ * @details See the STM32 reference manual, this register is used for
+ * the I2S clock setup.
+ */
+ int16_t i2spr;
+} I2SConfig;
+
+/**
+ * @brief Structure representing an I2S driver.
+ */
+struct I2SDriver {
+ /**
+ * @brief Driver state.
+ */
+ i2sstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const I2SConfig *config;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the SPIx registers block.
+ */
+ SPI_TypeDef *spi;
+ /**
+ * @brief DMA stream.
+ */
+ const stm32_dma_stream_t *dma;
+ /**
+ * @brief DMA mode bit mask.
+ */
+ uint32_t dmamode;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_I2S_USE_I2S2 && !defined(__DOXYGEN__)
+extern I2SDriver I2SD2;
+#endif
+
+#if STM32_I2S_USE_I2S3 && !defined(__DOXYGEN__)
+extern I2SDriver I2SD3;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void i2s_lld_init(void);
+ void i2s_lld_start(I2SDriver *i2sp);
+ void i2s_lld_stop(I2SDriver *i2sp);
+ void i2s_lld_start_exchange(I2SDriver *i2sp);
+ void i2s_lld_start_exchange_continuous(I2SDriver *i2sp);
+ void i2s_lld_stop_exchange(I2SDriver *i2sp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_I2S */
+
+#endif /* _I2S_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/icu_lld.c b/os/hal/platforms/STM32/icu_lld.c
index 2bfffd3bd..d5511ec01 100644
--- a/os/hal/platforms/STM32/icu_lld.c
+++ b/os/hal/platforms/STM32/icu_lld.c
@@ -17,6 +17,10 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/*
+ Concepts and parts of this file have been contributed by Fabio Utzig and
+ Xo Wang.
+ */
/**
* @file STM32/icu_lld.c
@@ -112,6 +116,8 @@ static void icu_lld_serve_interrupt(ICUDriver *icup) {
if ((sr & TIM_SR_CC2IF) != 0)
_icu_isr_invoke_period_cb(icup);
}
+ if ((sr & TIM_SR_UIF) != 0)
+ _icu_isr_invoke_overflow_cb(icup);
}
/*===========================================================================*/
@@ -276,7 +282,7 @@ void icu_lld_init(void) {
#if STM32_ICU_USE_TIM8
/* Driver initialization.*/
icuObjectInit(&ICUD8);
- ICUD5.tim = STM32_TIM8;
+ ICUD8.tim = STM32_TIM8;
#endif
}
@@ -344,8 +350,8 @@ void icu_lld_start(ICUDriver *icup) {
#endif
#if STM32_ICU_USE_TIM8
if (&ICUD8 == icup) {
- rccEnableTIM5(FALSE);
- rccResetTIM5();
+ rccEnableTIM8(FALSE);
+ rccResetTIM8();
nvicEnableVector(TIM8_CC_IRQn,
CORTEX_PRIORITY_MASK(STM32_ICU_TIM8_IRQ_PRIORITY));
icup->clock = STM32_TIMCLK2;
@@ -482,7 +488,7 @@ void icu_lld_stop(ICUDriver *icup) {
*/
void icu_lld_enable(ICUDriver *icup) {
- icup->tim->SR = 0; /* Clear pending IRQs (if any). */
+ icup->tim->SR = 0; /* Clear pending IRQs (if any). */
if (icup->config->channel == ICU_CHANNEL_1) {
if (icup->config->period_cb != NULL)
icup->tim->DIER |= TIM_DIER_CC1IE;
@@ -494,6 +500,8 @@ void icu_lld_enable(ICUDriver *icup) {
if (icup->config->period_cb != NULL)
icup->tim->DIER |= TIM_DIER_CC2IE;
}
+ if (icup->config->overflow_cb != NULL)
+ icup->tim->DIER |= TIM_DIER_UIE;
icup->tim->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
}
diff --git a/os/hal/platforms/STM32/icu_lld.h b/os/hal/platforms/STM32/icu_lld.h
index 642de2a64..691b06a71 100644
--- a/os/hal/platforms/STM32/icu_lld.h
+++ b/os/hal/platforms/STM32/icu_lld.h
@@ -227,6 +227,10 @@ typedef struct {
* @brief Callback for cycle period measurement.
*/
icucallback_t period_cb;
+ /**
+ * @brief Callback for timer overflow.
+ */
+ icucallback_t overflow_cb;
/* End of the mandatory fields.*/
/**
* @brief Timer input channel to be used.
diff --git a/os/hal/platforms/STM32/mac_lld.c b/os/hal/platforms/STM32/mac_lld.c
index 849c7a39e..15f9cd13c 100644
--- a/os/hal/platforms/STM32/mac_lld.c
+++ b/os/hal/platforms/STM32/mac_lld.c
@@ -118,14 +118,22 @@ static uint32_t mii_read(MACDriver *macp, uint32_t reg) {
static void mii_find_phy(MACDriver *macp) {
uint32_t i;
- for (i = 0; i < 31; i++) {
- macp->phyaddr = i << 11;
- ETH->MACMIIDR = (i << 6) | MACMIIDR_CR;
- if ((mii_read(macp, MII_PHYSID1) == (BOARD_PHY_ID >> 16)) &&
- ((mii_read(macp, MII_PHYSID2) & 0xFFF0) == (BOARD_PHY_ID & 0xFFF0))) {
- return;
+#if STM32_MAC_PHY_TIMEOUT > 0
+ halrtcnt_t start = halGetCounterValue();
+ halrtcnt_t timeout = start + MS2RTT(STM32_MAC_PHY_TIMEOUT);
+ while (halIsCounterWithin(start, timeout)) {
+#endif
+ for (i = 0; i < 31; i++) {
+ macp->phyaddr = i << 11;
+ ETH->MACMIIDR = (i << 6) | MACMIIDR_CR;
+ if ((mii_read(macp, MII_PHYSID1) == (BOARD_PHY_ID >> 16)) &&
+ ((mii_read(macp, MII_PHYSID2) & 0xFFF0) == (BOARD_PHY_ID & 0xFFF0))) {
+ return;
+ }
}
+#if STM32_MAC_PHY_TIMEOUT > 0
}
+#endif
/* Wrong or defective board.*/
chSysHalt();
}
@@ -242,7 +250,7 @@ void mac_lld_init(void) {
/* PHY address setup.*/
#if defined(BOARD_PHY_ADDRESS)
- phyaddr = BOARD_PHY_ADDRESS << 11;
+ ETHD1.phyaddr = BOARD_PHY_ADDRESS << 11;
#else
mii_find_phy(&ETHD1);
#endif
@@ -308,7 +316,11 @@ void mac_lld_start(MACDriver *macp) {
/* Transmitter and receiver enabled.
Note that the complete setup of the MAC is performed when the link
status is detected.*/
+#if STM32_IP_CHECKSUM_OFFLOAD
ETH->MACCR = ETH_MACCR_IPCO | ETH_MACCR_RE | ETH_MACCR_TE;
+#else
+ ETH->MACCR = ETH_MACCR_RE | ETH_MACCR_TE;
+#endif
/* DMA configuration:
Descriptor chains pointers.*/
@@ -411,7 +423,7 @@ msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
* @brief Writes to a transmit descriptor's stream.
*
* @param[in] tdp pointer to a @p MACTransmitDescriptor structure
- * @param[in] buf pointer to the buffer cointaining the data to be
+ * @param[in] buf pointer to the buffer containing the data to be
* written
* @param[in] size number of bytes to be written
* @return The number of bytes written into the descriptor's
@@ -457,7 +469,8 @@ void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) {
/* Unlocks the descriptor and returns it to the DMA engine.*/
tdp->physdesc->tdes1 = tdp->offset;
- tdp->physdesc->tdes0 = STM32_TDES0_IC | STM32_TDES0_LS | STM32_TDES0_FS |
+ tdp->physdesc->tdes0 = STM32_TDES0_CIC(STM32_IP_CHECKSUM_OFFLOAD) |
+ STM32_TDES0_IC | STM32_TDES0_LS | STM32_TDES0_FS |
STM32_TDES0_TCH | STM32_TDES0_OWN;
/* If the DMA engine is stalled then a restart request is issued.*/
@@ -492,8 +505,12 @@ msg_t max_lld_get_receive_descriptor(MACDriver *macp,
/* Iterates through received frames until a valid one is found, invalid
frames are discarded.*/
while (!(rdes->rdes0 & STM32_RDES0_OWN)) {
- if (!(rdes->rdes0 & (STM32_RDES0_AFM | STM32_RDES0_ES)) &&
- (rdes->rdes0 & STM32_RDES0_FS) && (rdes->rdes0 & STM32_RDES0_LS)) {
+ if (!(rdes->rdes0 & (STM32_RDES0_AFM | STM32_RDES0_ES
+#if STM32_IP_CHECKSUM_OFFLOAD
+ | STM32_RDES0_IPHCE | STM32_RDES0_PCE
+#endif
+ )) && (rdes->rdes0 & STM32_RDES0_FS) &&
+ (rdes->rdes0 & STM32_RDES0_LS)) {
/* Found a valid one.*/
rdp->offset = 0;
rdp->size = ((rdes->rdes0 & STM32_RDES0_FL_MASK) >> 16) - 4;
diff --git a/os/hal/platforms/STM32/mac_lld.h b/os/hal/platforms/STM32/mac_lld.h
index 077ddd2ec..3bedc38a2 100644
--- a/os/hal/platforms/STM32/mac_lld.h
+++ b/os/hal/platforms/STM32/mac_lld.h
@@ -84,6 +84,7 @@
#define STM32_TDES0_TTSE 0x02000000
#define STM32_TDES0_LOCKED 0x01000000 /* NOTE: Pseudo flag. */
#define STM32_TDES0_CIC_MASK 0x00C00000
+#define STM32_TDES0_CIC(n) ((n) << 22)
#define STM32_TDES0_TER 0x00200000
#define STM32_TDES0_TCH 0x00100000
#define STM32_TDES0_TTSS 0x00020000
@@ -141,17 +142,51 @@
#endif
/**
+ * @brief PHY detection timeout.
+ * @details Timeout, in milliseconds, for PHY address detection, if a PHY
+ * is not detected within the timeout then the driver halts during
+ * initialization. This setting applies only if the PHY address is
+ * not explicitly set in the board header file using
+ * @p BOARD_PHY_ADDRESS. A zero value disables the timeout and a
+ * single search path is performed.
+ */
+#if !defined(STM32_MAC_PHY_TIMEOUT) || defined(__DOXYGEN__)
+#define STM32_MAC_PHY_TIMEOUT 100
+#endif
+
+/**
* @brief ETHD1 interrupt priority level setting.
*/
#if !defined(STM32_ETH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ETH1_IRQ_PRIORITY 13
#endif
+
+/**
+ * @brief IP checksum offload.
+ * @details The following modes are available:
+ * - 0 Function disabled.
+ * - 1 Only IP header checksum calculation and insertion are enabled.
+ * - 2 IP header checksum and payload checksum calculation and
+ * insertion are enabled, but pseudo-header checksum is not
+ * calculated in hardware.
+ * - 3 IP Header checksum and payload checksum calculation and
+ * insertion are enabled, and pseudo-header checksum is
+ * calculated in hardware.
+ * .
+ */
+#if !defined(STM32_IP_CHECKSUM_OFFLOAD) || defined(__DOXYGEN__)
+#define STM32_IP_CHECKSUM_OFFLOAD 0
+#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
+#if (STM32_MAC_PHY_TIMEOUT > 0) && !HAL_IMPLEMENTS_COUNTERS
+#error "STM32_MAC_PHY_TIMEOUT requires the realtime counter service"
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c
index 61d91b044..d3f251b99 100644
--- a/os/hal/platforms/STM32/sdc_lld.c
+++ b/os/hal/platforms/STM32/sdc_lld.c
@@ -374,7 +374,7 @@ void sdc_lld_stop(SDCDriver *sdcp) {
}
/**
- * @brief Starts the SDIO clock and sets it to init mode (400KHz or less).
+ * @brief Starts the SDIO clock and sets it to init mode (400kHz or less).
*
* @param[in] sdcp pointer to the @p SDCDriver object
*
@@ -383,7 +383,7 @@ void sdc_lld_stop(SDCDriver *sdcp) {
void sdc_lld_start_clk(SDCDriver *sdcp) {
(void)sdcp;
- /* Initial clock setting: 400KHz, 1bit mode.*/
+ /* Initial clock setting: 400kHz, 1bit mode.*/
SDIO->CLKCR = STM32_SDIO_DIV_LS;
SDIO->POWER |= SDIO_POWER_PWRCTRL_0 | SDIO_POWER_PWRCTRL_1;
SDIO->CLKCR |= SDIO_CLKCR_CLKEN;
diff --git a/os/hal/platforms/STM32/serial_lld.h b/os/hal/platforms/STM32/serial_lld.h
index 41d10c080..7589da600 100644
--- a/os/hal/platforms/STM32/serial_lld.h
+++ b/os/hal/platforms/STM32/serial_lld.h
@@ -108,7 +108,7 @@
* @brief USART2 interrupt priority level setting.
*/
#if !defined(STM32_SERIAL_USART2_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART2_PRIORITY 12)
+#define STM32_SERIAL_USART2_PRIORITY 12
#endif
/**
diff --git a/os/hal/platforms/STM32F1xx/platform.dox b/os/hal/platforms/STM32F1xx/platform.dox
index c9e9bf1a3..0dc3a988b 100644
--- a/os/hal/platforms/STM32F1xx/platform.dox
+++ b/os/hal/platforms/STM32F1xx/platform.dox
@@ -388,7 +388,7 @@
* @section stm32f1xx_rcc_2 STM32F1xx RCC driver implementation features
* - Peripherals reset.
* - Peripherals clock enable.
- * - Periplerals clock disable.
+ * - Peripherals clock disable.
* .
* @ingroup STM32F1xx_PLATFORM_DRIVERS
*/
diff --git a/os/hal/platforms/STM32F1xx/stm32_dma.c b/os/hal/platforms/STM32F1xx/stm32_dma.c
index 59987cd82..8e0622218 100644
--- a/os/hal/platforms/STM32F1xx/stm32_dma.c
+++ b/os/hal/platforms/STM32F1xx/stm32_dma.c
@@ -29,7 +29,7 @@
* drivers to coordinate the access to the resource.
* @note The DMA ISR handlers are all declared into this module because
* sharing, the various device drivers can associate a callback to
- * IRSs when allocating streams.
+ * ISRs when allocating streams.
* @{
*/
diff --git a/os/hal/platforms/STM32F2xx/adc_lld.h b/os/hal/platforms/STM32F2xx/adc_lld.h
index 737fa05c9..0ed939462 100644
--- a/os/hal/platforms/STM32F2xx/adc_lld.h
+++ b/os/hal/platforms/STM32F2xx/adc_lld.h
@@ -40,12 +40,12 @@
* @{
*/
/**
- * @brief Maximum HSE clock frequency.
+ * @brief Minimum ADC clock frequency.
*/
#define STM32_ADCCLK_MIN 600000
/**
- * @brief Maximum HSE clock frequency.
+ * @brief Maximum ADC clock frequency.
*/
#define STM32_ADCCLK_MAX 30000000
/** @} */
diff --git a/os/hal/platforms/STM32F2xx/hal_lld.h b/os/hal/platforms/STM32F2xx/hal_lld.h
index 165a10448..c93aa29a7 100644
--- a/os/hal/platforms/STM32F2xx/hal_lld.h
+++ b/os/hal/platforms/STM32F2xx/hal_lld.h
@@ -400,10 +400,10 @@
#define STM32_HAS_USART3 TRUE
#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_USART3_RX_DMA_CHN 0x00400400
+#define STM32_USART3_RX_DMA_CHN 0x00000040
#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) | \
STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART3_TX_DMA_CHN 0x00074040
+#define STM32_USART3_TX_DMA_CHN 0x00074000
#define STM32_HAS_UART4 TRUE
#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
diff --git a/os/hal/platforms/STM32F2xx/platform.dox b/os/hal/platforms/STM32F2xx/platform.dox
index e247a1779..536a9780a 100644
--- a/os/hal/platforms/STM32F2xx/platform.dox
+++ b/os/hal/platforms/STM32F2xx/platform.dox
@@ -306,7 +306,7 @@
* @section stm32f2xx_rcc_2 STM32F2xx RCC driver implementation features
* - Peripherals reset.
* - Peripherals clock enable.
- * - Periplerals clock disable.
+ * - Peripherals clock disable.
* .
* @ingroup STM32F2xx_PLATFORM_DRIVERS
*/
diff --git a/os/hal/platforms/STM32F2xx/platform.mk b/os/hal/platforms/STM32F2xx/platform.mk
index 37b37bc93..92dca2228 100644
--- a/os/hal/platforms/STM32F2xx/platform.mk
+++ b/os/hal/platforms/STM32F2xx/platform.mk
@@ -6,17 +6,18 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F2xx/stm32_dma.c \
${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/i2c_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/icu_lld.c \
+ ${CHIBIOS}/os/hal/platforms/STM32/mac_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/pwm_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \
+ ${CHIBIOS}/os/hal/platforms/STM32/OTGv1/usb_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/RTCv2/rtc_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32F2xx \
${CHIBIOS}/os/hal/platforms/STM32 \
${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 \
- ${CHIBIOS}/os/hal/platforms/STM32/RTCv2 \
-
-
+ ${CHIBIOS}/os/hal/platforms/STM32/OTGv1 \
+ ${CHIBIOS}/os/hal/platforms/STM32/RTCv2
diff --git a/os/hal/platforms/STM32F2xx/stm32_dma.c b/os/hal/platforms/STM32F2xx/stm32_dma.c
index 3c1aac444..8e0226747 100644
--- a/os/hal/platforms/STM32F2xx/stm32_dma.c
+++ b/os/hal/platforms/STM32F2xx/stm32_dma.c
@@ -29,7 +29,7 @@
* drivers to coordinate the access to the resource.
* @note The DMA ISR handlers are all declared into this module because
* sharing, the various device drivers can associate a callback to
- * IRSs when allocating streams.
+ * ISRs when allocating streams.
* @{
*/
diff --git a/os/hal/platforms/STM32F2xx/stm32_rcc.h b/os/hal/platforms/STM32F2xx/stm32_rcc.h
index c624279ea..af070d814 100644
--- a/os/hal/platforms/STM32F2xx/stm32_rcc.h
+++ b/os/hal/platforms/STM32F2xx/stm32_rcc.h
@@ -423,6 +423,42 @@
/** @} */
/**
+ * @name ETH peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the ETH peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableETH(lp) rccEnableAHB1(RCC_AHB1ENR_ETHMACEN | \
+ RCC_AHB1ENR_ETHMACTXEN | \
+ RCC_AHB1ENR_ETHMACRXEN, lp)
+
+/**
+ * @brief Disables the ETH peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccDisableETH(lp) rccDisableAHB1(RCC_AHB1ENR_ETHMACEN | \
+ RCC_AHB1ENR_ETHMACTXEN | \
+ RCC_AHB1ENR_ETHMACRXEN, lp)
+
+/**
+ * @brief Resets the ETH peripheral.
+ *
+ * @api
+ */
+#define rccResetETH() rccResetAHB1(RCC_AHB1RSTR_ETHMACRST)
+/** @} */
+
+/**
* @name I2C peripherals specific RCC operations
* @{
*/
@@ -503,6 +539,36 @@
/** @} */
/**
+ * @name OTG peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the OTG_FS peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableOTG_FS(lp) rccEnableAHB2(RCC_AHB2LPENR_OTGFSLPEN, lp)
+
+/**
+ * @brief Disables the OTG_FS peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccDisableOTG_FS(lp) rccEnableAHB2(RCC_AHB2LPENR_OTGFSLPEN, lp)
+
+/**
+ * @brief Resets the OTG_FS peripheral.
+ *
+ * @api
+ */
+#define rccResetOTG_FS() rccResetAHB2(RCC_AHB2RSTR_OTGFSRST)
+/** @} */
+
+/**
* @name SPI peripherals specific RCC operations
* @{
*/
diff --git a/os/hal/platforms/STM32F4xx/adc_lld.h b/os/hal/platforms/STM32F4xx/adc_lld.h
index 21723bd70..5f8a8d179 100644
--- a/os/hal/platforms/STM32F4xx/adc_lld.h
+++ b/os/hal/platforms/STM32F4xx/adc_lld.h
@@ -40,12 +40,12 @@
* @{
*/
/**
- * @brief Maximum HSE clock frequency.
+ * @brief Minimum ADC clock frequency.
*/
#define STM32_ADCCLK_MIN 600000
/**
- * @brief Maximum HSE clock frequency.
+ * @brief Maximum ADC clock frequency.
*/
#define STM32_ADCCLK_MAX 36000000
/** @} */
diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h
index 3585379e4..06bd3e198 100644
--- a/os/hal/platforms/STM32F4xx/hal_lld.h
+++ b/os/hal/platforms/STM32F4xx/hal_lld.h
@@ -402,10 +402,10 @@
#define STM32_HAS_USART3 TRUE
#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_USART3_RX_DMA_CHN 0x00400400
+#define STM32_USART3_RX_DMA_CHN 0x00000040
#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) | \
STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART3_TX_DMA_CHN 0x00074040
+#define STM32_USART3_TX_DMA_CHN 0x00074000
#define STM32_HAS_UART4 TRUE
#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
diff --git a/os/hal/platforms/STM32F4xx/platform.dox b/os/hal/platforms/STM32F4xx/platform.dox
index 7b847ee0b..386924d42 100644
--- a/os/hal/platforms/STM32F4xx/platform.dox
+++ b/os/hal/platforms/STM32F4xx/platform.dox
@@ -306,7 +306,7 @@
* @section stm32f4xx_rcc_2 STM32F4xx RCC driver implementation features
* - Peripherals reset.
* - Peripherals clock enable.
- * - Periplerals clock disable.
+ * - Peripherals clock disable.
* .
* @ingroup STM32F4xx_PLATFORM_DRIVERS
*/
diff --git a/os/hal/platforms/STM32F4xx/platform.mk b/os/hal/platforms/STM32F4xx/platform.mk
index fa9caef41..5194488b8 100644
--- a/os/hal/platforms/STM32F4xx/platform.mk
+++ b/os/hal/platforms/STM32F4xx/platform.mk
@@ -6,16 +6,19 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F4xx/stm32_dma.c \
${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/i2c_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/icu_lld.c \
+ ${CHIBIOS}/os/hal/platforms/STM32/mac_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/pwm_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \
+ ${CHIBIOS}/os/hal/platforms/STM32/OTGv1/usb_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/RTCv2/rtc_lld.c \
- ${CHIBIOS}/os/hal/platforms/STM32/RTCv2/sdc_lld.c
+ ${CHIBIOS}/os/hal/platforms/STM32/sdc_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32F4xx \
${CHIBIOS}/os/hal/platforms/STM32 \
${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 \
- ${CHIBIOS}/os/hal/platforms/STM32/RTCv2
+ ${CHIBIOS}/os/hal/platforms/STM32/OTGv1 \
+ ${CHIBIOS}/os/hal/platforms/STM32/RTCv2 \ No newline at end of file
diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.c b/os/hal/platforms/STM32F4xx/stm32_dma.c
index 46a68a8e1..32d7eafcf 100644
--- a/os/hal/platforms/STM32F4xx/stm32_dma.c
+++ b/os/hal/platforms/STM32F4xx/stm32_dma.c
@@ -29,7 +29,7 @@
* drivers to coordinate the access to the resource.
* @note The DMA ISR handlers are all declared into this module because
* sharing, the various device drivers can associate a callback to
- * IRSs when allocating streams.
+ * ISRs when allocating streams.
* @{
*/
diff --git a/os/hal/platforms/STM32F4xx/stm32_rcc.h b/os/hal/platforms/STM32F4xx/stm32_rcc.h
index 181a2547c..0ba4a392d 100644
--- a/os/hal/platforms/STM32F4xx/stm32_rcc.h
+++ b/os/hal/platforms/STM32F4xx/stm32_rcc.h
@@ -423,6 +423,42 @@
/** @} */
/**
+ * @name ETH peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the ETH peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableETH(lp) rccEnableAHB1(RCC_AHB1ENR_ETHMACEN | \
+ RCC_AHB1ENR_ETHMACTXEN | \
+ RCC_AHB1ENR_ETHMACRXEN, lp)
+
+/**
+ * @brief Disables the ETH peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccDisableETH(lp) rccDisableAHB1(RCC_AHB1ENR_ETHMACEN | \
+ RCC_AHB1ENR_ETHMACTXEN | \
+ RCC_AHB1ENR_ETHMACRXEN, lp)
+
+/**
+ * @brief Resets the ETH peripheral.
+ *
+ * @api
+ */
+#define rccResetETH() rccResetAHB1(RCC_AHB1RSTR_ETHMACRST)
+/** @} */
+
+/**
* @name I2C peripherals specific RCC operations
* @{
*/
@@ -503,6 +539,36 @@
/** @} */
/**
+ * @name OTG peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the OTG_FS peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableOTG_FS(lp) rccEnableAHB2(RCC_AHB2LPENR_OTGFSLPEN, lp)
+
+/**
+ * @brief Disables the OTG_FS peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccDisableOTG_FS(lp) rccEnableAHB2(RCC_AHB2LPENR_OTGFSLPEN, lp)
+
+/**
+ * @brief Resets the OTG_FS peripheral.
+ *
+ * @api
+ */
+#define rccResetOTG_FS() rccResetAHB2(RCC_AHB2RSTR_OTGFSRST)
+/** @} */
+
+/**
* @name SDIO peripheral specific RCC operations
* @{
*/
diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h
index f7402dfe6..38f910f2d 100644
--- a/os/hal/platforms/STM32L1xx/hal_lld.h
+++ b/os/hal/platforms/STM32L1xx/hal_lld.h
@@ -149,10 +149,10 @@
* @{
*/
#define STM32_MSIRANGE_MASK (7 << 13) /**< MSIRANGE field mask. */
-#define STM32_MSIRANGE_64K (0 << 13) /**< 64KHz nominal. */
-#define STM32_MSIRANGE_128K (1 << 13) /**< 128KHz nominal. */
-#define STM32_MSIRANGE_256K (2 << 13) /**< 256KHz nominal. */
-#define STM32_MSIRANGE_512K (3 << 13) /**< 512KHz nominal. */
+#define STM32_MSIRANGE_64K (0 << 13) /**< 64kHz nominal. */
+#define STM32_MSIRANGE_128K (1 << 13) /**< 128kHz nominal. */
+#define STM32_MSIRANGE_256K (2 << 13) /**< 256kHz nominal. */
+#define STM32_MSIRANGE_512K (3 << 13) /**< 512kHz nominal. */
#define STM32_MSIRANGE_1M (4 << 13) /**< 1MHz nominal. */
#define STM32_MSIRANGE_2M (5 << 13) /**< 2MHz nominal. */
#define STM32_MSIRANGE_4M (6 << 13) /**< 4MHz nominal */
@@ -678,7 +678,7 @@
#error "impossible to activate LSE"
#endif
#if (STM32_LSECLK < 1000) || (STM32_LSECLK > 1000000)
-#error "STM32_LSECLK outside acceptable range (1...1000KHz)"
+#error "STM32_LSECLK outside acceptable range (1...1000kHz)"
#endif
#else /* !STM32_LSE_ENABLED */
#if STM_RTCCLK == STM32_LSECLK
diff --git a/os/hal/platforms/STM32L1xx/platform.dox b/os/hal/platforms/STM32L1xx/platform.dox
index 744f1b673..fe845811e 100644
--- a/os/hal/platforms/STM32L1xx/platform.dox
+++ b/os/hal/platforms/STM32L1xx/platform.dox
@@ -305,7 +305,7 @@
* @section stm32l1xx_rcc_2 STM32L1xx RCC driver implementation features
* - Peripherals reset.
* - Peripherals clock enable.
- * - Periplerals clock disable.
+ * - Peripherals clock disable.
* .
* @ingroup STM32L1xx_PLATFORM_DRIVERS
*/
diff --git a/os/hal/platforms/STM32L1xx/stm32_dma.c b/os/hal/platforms/STM32L1xx/stm32_dma.c
index 85841ad9f..0e6d52404 100644
--- a/os/hal/platforms/STM32L1xx/stm32_dma.c
+++ b/os/hal/platforms/STM32L1xx/stm32_dma.c
@@ -29,7 +29,7 @@
* drivers to coordinate the access to the resource.
* @note The DMA ISR handlers are all declared into this module because
* sharing, the various device drivers can associate a callback to
- * IRSs when allocating streams.
+ * ISRs when allocating streams.
* @{
*/
diff --git a/os/hal/platforms/STM32L1xx/stm32l1xx.h b/os/hal/platforms/STM32L1xx/stm32l1xx.h
index 9c665d29b..0870e768e 100644
--- a/os/hal/platforms/STM32L1xx/stm32l1xx.h
+++ b/os/hal/platforms/STM32L1xx/stm32l1xx.h
@@ -2602,10 +2602,10 @@ typedef struct
#define RCC_ICSCR_HSITRIM ((uint32_t)0x00001F00) /*!< Internal High Speed clock trimming */
#define RCC_ICSCR_MSIRANGE ((uint32_t)0x0000E000) /*!< Internal Multi Speed clock Range */
-#define RCC_ICSCR_MSIRANGE_0 ((uint32_t)0x00000000) /*!< Internal Multi Speed clock Range 65.536 KHz */
-#define RCC_ICSCR_MSIRANGE_1 ((uint32_t)0x00002000) /*!< Internal Multi Speed clock Range 131.072 KHz */
-#define RCC_ICSCR_MSIRANGE_2 ((uint32_t)0x00004000) /*!< Internal Multi Speed clock Range 262.144 KHz */
-#define RCC_ICSCR_MSIRANGE_3 ((uint32_t)0x00006000) /*!< Internal Multi Speed clock Range 524.288 KHz */
+#define RCC_ICSCR_MSIRANGE_0 ((uint32_t)0x00000000) /*!< Internal Multi Speed clock Range 65.536 kHz */
+#define RCC_ICSCR_MSIRANGE_1 ((uint32_t)0x00002000) /*!< Internal Multi Speed clock Range 131.072 kHz */
+#define RCC_ICSCR_MSIRANGE_2 ((uint32_t)0x00004000) /*!< Internal Multi Speed clock Range 262.144 kHz */
+#define RCC_ICSCR_MSIRANGE_3 ((uint32_t)0x00006000) /*!< Internal Multi Speed clock Range 524.288 kHz */
#define RCC_ICSCR_MSIRANGE_4 ((uint32_t)0x00008000) /*!< Internal Multi Speed clock Range 1.048 MHz */
#define RCC_ICSCR_MSIRANGE_5 ((uint32_t)0x0000A000) /*!< Internal Multi Speed clock Range 2.097 MHz */
#define RCC_ICSCR_MSIRANGE_6 ((uint32_t)0x0000C000) /*!< Internal Multi Speed clock Range 4.194 MHz */
diff --git a/os/hal/platforms/STM8L/hal_lld.c b/os/hal/platforms/STM8L/hal_lld.c
index 5cfc5b0cd..4ba2076a7 100644
--- a/os/hal/platforms/STM8L/hal_lld.c
+++ b/os/hal/platforms/STM8L/hal_lld.c
@@ -108,7 +108,7 @@ void hal_lld_init(void) {
#endif
/* Clocks initially all disabled, note the boot ROM clock is disabled
- because the boot loader is no more required and it draws pretious uAs.*/
+ because the boot loader is no more required and it draws precious uAs.*/
CLK->PCKENR1 = 0;
CLK->PCKENR2 = 0;
CLK->PCKENR3 = 0;
diff --git a/os/hal/src/i2s.c b/os/hal/src/i2s.c
new file mode 100644
index 000000000..99e4246ad
--- /dev/null
+++ b/os/hal/src/i2s.c
@@ -0,0 +1,179 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file i2s.c
+ * @brief I2S Driver code.
+ *
+ * @addtogroup I2S
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_I2S || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief I2S Driver initialization.
+ * @note This function is implicitly invoked by @p halInit(), there is
+ * no need to explicitly initialize the driver.
+ *
+ * @init
+ */
+void i2sInit(void) {
+
+ i2s_lld_init();
+}
+
+/**
+ * @brief Initializes the standard part of a @p I2SDriver structure.
+ *
+ * @param[out] i2sp pointer to the @p I2SDriver object
+ *
+ * @init
+ */
+void i2sObjectInit(I2SDriver *i2sp) {
+
+ i2sp->state = I2S_STOP;
+ i2sp->config = NULL;
+}
+
+/**
+ * @brief Configures and activates the I2S peripheral.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ * @param[in] config pointer to the @p I2SConfig object
+ *
+ * @api
+ */
+void i2sStart(I2SDriver *i2sp, const I2SConfig *config) {
+
+ chDbgCheck((i2sp != NULL) && (config != NULL), "i2sStart");
+
+ chSysLock();
+ chDbgAssert((i2sp->state == I2S_STOP) || (i2sp->state == I2S_READY),
+ "i2sStart(), #1", "invalid state");
+ i2sp->config = config;
+ i2s_lld_start(i2sp);
+ i2sp->state = I2S_READY;
+ chSysUnlock();
+}
+
+/**
+ * @brief Deactivates the I2S peripheral.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @api
+ */
+void i2sStop(I2SDriver *i2sp) {
+
+ chDbgCheck(i2sp != NULL, "i2sStop");
+
+ chSysLock();
+ chDbgAssert((i2sp->state == I2S_STOP) || (i2sp->state == I2S_READY),
+ "i2sStop(), #1", "invalid state");
+ i2s_lld_stop(i2sp);
+ i2sp->state = I2S_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Starts a I2S data exchange.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @api
+ */
+void i2sStartExchange(I2SDriver *i2sp) {
+
+ chDbgCheck(i2sp != NULL "i2sStartExchange");
+
+ chSysLock();
+ chDbgAssert(i2sp->state == I2S_READY,
+ "i2sStartExchange(), #1", "not ready");
+ i2sStartExchangeI(i2sp);
+ chSysUnlock();
+}
+
+/**
+ * @brief Starts a I2S data exchange in continuous mode.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @api
+ */
+void i2sStartExchangeContinuous(I2SDriver *i2sp) {
+
+ chDbgCheck(i2sp != NULL "i2sStartExchangeContinuous");
+
+ chSysLock();
+ chDbgAssert(i2sp->state == I2S_READY,
+ "i2sStartExchangeContinuous(), #1", "not ready");
+ i2sStartExchangeContinuousI(i2sp);
+ chSysUnlock();
+}
+
+/**
+ * @brief Stops the ongoing data exchange.
+ * @details The ongoing data exchange, if any, is stopped, if the driver
+ * was not active the function does nothing.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @api
+ */
+void i2sStopExchange(I2SDriver *i2sp) {
+
+ chDbgCheck((i2sp != NULL), "i2sStopExchange");
+
+ chSysLock();
+ chDbgAssert((i2sp->state == I2S_READY) ||
+ (i2sp->state == I2S_ACTIVE) ||
+ (i2sp->state == I2S_COMPLETE),
+ "i2sStopExchange(), #1", "not ready");
+ i2sStopExchangeI(i2sp);
+ chSysUnlock();
+}
+
+#endif /* HAL_USE_I2S */
+
+/** @} */
diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c
index c7b3372f2..c022e4a68 100644
--- a/os/hal/src/mmc_spi.c
+++ b/os/hal/src/mmc_spi.c
@@ -96,7 +96,7 @@ static uint8_t crc7(uint8_t crc, const uint8_t *buffer, size_t len) {
}
/**
- * @brief Inserion monitor timer callback function.
+ * @brief Insertion monitor timer callback function.
*
* @param[in] p pointer to the @p MMCDriver object
*
diff --git a/os/hal/templates/halconf.h b/os/hal/templates/halconf.h
index 6f4279ec4..f28d8f030 100644
--- a/os/hal/templates/halconf.h
+++ b/os/hal/templates/halconf.h
@@ -292,7 +292,7 @@
/**
* @brief Number of initialization attempts before rejecting the card.
- * @note Attempts are performed at 10mS intevals.
+ * @note Attempts are performed at 10mS intervals.
*/
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
#define SDC_INIT_RETRY 100
diff --git a/os/hal/templates/icu_lld.h b/os/hal/templates/icu_lld.h
index 4b0568102..56ce3af98 100644
--- a/os/hal/templates/icu_lld.h
+++ b/os/hal/templates/icu_lld.h
@@ -17,6 +17,10 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/*
+ Concepts and parts of this file have been contributed by Fabio Utzig and
+ Xo Wang.
+ */
/**
* @file templates/icu_lld.h
@@ -88,6 +92,10 @@ typedef struct {
* @brief Callback for cycle period measurement.
*/
icucallback_t period_cb;
+ /**
+ * @brief Callback for timer overflow.
+ */
+ icucallback_t overflow_cb;
/* End of the mandatory fields.*/
} ICUConfig;
diff --git a/os/hal/templates/mac_lld.c b/os/hal/templates/mac_lld.c
index f8d99e330..41c8f331a 100644
--- a/os/hal/templates/mac_lld.c
+++ b/os/hal/templates/mac_lld.c
@@ -114,7 +114,7 @@ msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
* @brief Writes to a transmit descriptor's stream.
*
* @param[in] tdp pointer to a @p MACTransmitDescriptor structure
- * @param[in] buf pointer to the buffer cointaining the data to be
+ * @param[in] buf pointer to the buffer containing the data to be
* written
* @param[in] size number of bytes to be written
* @return The number of bytes written into the descriptor's
diff --git a/os/kernel/include/chioch.h b/os/kernel/include/chioch.h
index e9c1044ce..27e2abbb4 100644
--- a/os/kernel/include/chioch.h
+++ b/os/kernel/include/chioch.h
@@ -317,7 +317,7 @@ typedef struct {
/**
* @brief Adds status flags to the channel's mask.
- * @details This function is usually called from the I/O ISTs in order to
+ * @details This function is usually called from the I/O ISRs in order to
* notify I/O conditions such as data events, errors, signal
* changes etc.
*
diff --git a/os/kernel/include/chmempools.h b/os/kernel/include/chmempools.h
index 8a0d6f47d..a920e2579 100644
--- a/os/kernel/include/chmempools.h
+++ b/os/kernel/include/chmempools.h
@@ -75,10 +75,50 @@ typedef struct {
#define MEMORYPOOL_DECL(name, size, provider) \
MemoryPool name = _MEMORYPOOL_DATA(name, size, provider)
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Adds an object to a memory pool.
+ * @pre The memory pool must be already been initialized.
+ * @pre The added object must be of the right size for the specified
+ * memory pool.
+ * @pre The added object must be memory aligned to the size of
+ * @p stkalign_t type.
+ * @note This function is just an alias for @p chPoolFree() and has been
+ * added for clarity.
+ *
+ * @param[in] mp pointer to a @p MemoryPool structure
+ * @param[in] objp the pointer to the object to be added
+ *
+ * @api
+ */
+#define chPoolAdd(mp, objp) chPoolFree(mp, objp)
+
+/**
+ * @brief Adds an object to a memory pool.
+ * @pre The memory pool must be already been initialized.
+ * @pre The added object must be of the right size for the specified
+ * memory pool.
+ * @pre The added object must be memory aligned to the size of
+ * @p stkalign_t type.
+ * @note This function is just an alias for @p chPoolFree() and has been
+ * added for clarity.
+ *
+ * @param[in] mp pointer to a @p MemoryPool structure
+ * @param[in] objp the pointer to the object to be added
+ *
+ * @iclass
+ */
+#define chPoolAddI(mp, objp) chPoolFreeI(mp, objp)
+/** @} */
+
#ifdef __cplusplus
extern "C" {
#endif
void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider);
+ void chPoolLoadArray(MemoryPool *mp, void *p, size_t n);
void *chPoolAllocI(MemoryPool *mp);
void *chPoolAlloc(MemoryPool *mp);
void chPoolFreeI(MemoryPool *mp, void *objp);
diff --git a/os/kernel/include/chschd.h b/os/kernel/include/chschd.h
index 215398659..3d1d37f7c 100644
--- a/os/kernel/include/chschd.h
+++ b/os/kernel/include/chschd.h
@@ -205,7 +205,7 @@ extern "C" {
#endif /* !defined(PORT_OPTIMIZED_DOYIELDS) */
/**
- * @brief Inlineable preemption code.
+ * @brief Inline-able preemption code.
* @details This is the common preemption code, this function must be invoked
* exclusively from the port layer.
*
diff --git a/os/kernel/include/chvt.h b/os/kernel/include/chvt.h
index 355f66064..5d4f674fc 100644
--- a/os/kernel/include/chvt.h
+++ b/os/kernel/include/chvt.h
@@ -46,7 +46,7 @@
#define S2ST(sec) ((systime_t)((sec) * CH_FREQUENCY))
/**
- * @brief Milliseconds t0 system ticks.
+ * @brief Milliseconds to system ticks.
* @details Converts from milliseconds to system ticks number.
* @note The result is rounded upward to the next tick boundary.
*
diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c
index 6749255e8..2b3247543 100644
--- a/os/kernel/src/chevents.c
+++ b/os/kernel/src/chevents.c
@@ -376,7 +376,7 @@ eventmask_t chEvtWaitAll(eventmask_t mask) {
* This means that Event Listeners with a lower event identifier have
* an higher priority.
*
- * @param[in] mask mask of the event flagss that the function should wait
+ * @param[in] mask mask of the event flags that the function should wait
* for, @p ALL_EVENTS enables all the events
* @param[in] time the number of ticks before the operation timeouts,
* the following special values are allowed:
diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c
index f84276779..1e7f99dce 100644
--- a/os/kernel/src/chheap.c
+++ b/os/kernel/src/chheap.c
@@ -31,7 +31,7 @@
* are guaranteed to be thread safe.<br>
* By enabling the @p CH_USE_MALLOC_HEAP option the heap manager
* will use the runtime-provided @p malloc() and @p free() as
- * backend for the heap APIs instead of the system provided
+ * back end for the heap APIs instead of the system provided
* allocator.
* @pre In order to use the heap APIs the @p CH_USE_HEAP option must
* be enabled in @p chconf.h.
diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c
index 86f88dce7..163f93f20 100644
--- a/os/kernel/src/chmboxes.c
+++ b/os/kernel/src/chmboxes.c
@@ -364,6 +364,7 @@ msg_t chMBFetchI(Mailbox *mbp, msg_t *msgp) {
if (chSemGetCounterI(&mbp->mb_fullsem) <= 0)
return RDY_TIMEOUT;
+ chSemFastWaitI(&mbp->mb_fullsem);
*msgp = *mbp->mb_rdptr++;
if (mbp->mb_rdptr >= mbp->mb_top)
mbp->mb_rdptr = mbp->mb_buffer;
diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c
index 6d1f7e866..8ef5cc403 100644
--- a/os/kernel/src/chmempools.c
+++ b/os/kernel/src/chmempools.c
@@ -61,7 +61,33 @@ void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) {
}
/**
+ * @brief Loads a memory pool with an array of static objects.
+ * @pre The memory pool must be already been initialized.
+ * @pre The array elements must be of the right size for the specified
+ * memory pool.
+ * @post The memory pool contains the elements of the input array.
+ *
+ * @param[in] mp pointer to a @p MemoryPool structure
+ * @param[in] p pointer to the array first element
+ * @param[in] n number of elements in the array
+ *
+ * @api
+ */
+void chPoolLoadArray(MemoryPool *mp, void *p, size_t n) {
+
+ chDbgCheck((mp != NULL) && MEM_IS_ALIGNED(p) && (n != 0),
+ "chPoolLoadArray");
+
+ while (n) {
+ chPoolAdd(mp, p);
+ p = (void *)(((uint8_t *)p) + mp->mp_object_size);
+ n--;
+ }
+}
+
+/**
* @brief Allocates an object from a memory pool.
+ * @pre The memory pool must be already been initialized.
*
* @param[in] mp pointer to a @p MemoryPool structure
* @return The pointer to the allocated object.
@@ -84,6 +110,7 @@ void *chPoolAllocI(MemoryPool *mp) {
/**
* @brief Allocates an object from a memory pool.
+ * @pre The memory pool must be already been initialized.
*
* @param[in] mp pointer to a @p MemoryPool structure
* @return The pointer to the allocated object.
@@ -101,14 +128,15 @@ void *chPoolAlloc(MemoryPool *mp) {
}
/**
- * @brief Releases (or adds) an object into (to) a memory pool.
+ * @brief Releases an object into a memory pool.
+ * @pre The memory pool must be already been initialized.
* @pre The freed object must be of the right size for the specified
* memory pool.
* @pre The freed object must be memory aligned to the size of
* @p stkalign_t type.
*
* @param[in] mp pointer to a @p MemoryPool structure
- * @param[in] objp the pointer to the object to be released or added
+ * @param[in] objp the pointer to the object to be released
*
* @iclass
*/
@@ -124,14 +152,15 @@ void chPoolFreeI(MemoryPool *mp, void *objp) {
}
/**
- * @brief Releases (or adds) an object into (to) a memory pool.
+ * @brief Releases an object into a memory pool.
+ * @pre The memory pool must be already been initialized.
* @pre The freed object must be of the right size for the specified
* memory pool.
* @pre The freed object must be memory aligned to the size of
* @p stkalign_t type.
*
* @param[in] mp pointer to a @p MemoryPool structure
- * @param[in] objp the pointer to the object to be released or added
+ * @param[in] objp the pointer to the object to be released
*
* @api
*/
@@ -141,6 +170,7 @@ void chPoolFree(MemoryPool *mp, void *objp) {
chPoolFreeI(mp, objp);
chSysUnlock();
}
+
#endif /* CH_USE_MEMPOOLS */
/** @} */
diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c
index 975a63094..20a4700fe 100644
--- a/os/kernel/src/chmtx.c
+++ b/os/kernel/src/chmtx.c
@@ -117,14 +117,14 @@ void chMtxLockS(Mutex *mp) {
chDbgCheckClassS();
chDbgCheck(mp != NULL, "chMtxLockS");
- /* Ia the mutex already locked? */
+ /* Is the mutex already locked? */
if (mp->m_owner != NULL) {
/* Priority inheritance protocol; explores the thread-mutex dependencies
boosting the priority of all the affected threads to equal the priority
of the running thread requesting the mutex.*/
Thread *tp = mp->m_owner;
/* Does the running thread have higher priority than the mutex
- ownning thread? */
+ owning thread? */
while (tp->p_prio < ctp->p_prio) {
/* Make priority of thread tp match the running thread's priority.*/
tp->p_prio = ctp->p_prio;
@@ -258,7 +258,7 @@ Mutex *chMtxUnlock(void) {
chDbgAssert(ctp->p_mtxlist->m_owner == ctp,
"chMtxUnlock(), #2",
"ownership failure");
- /* Removes the top Mutex from the Threads's owned mutexes list and matk it
+ /* Removes the top Mutex from the Thread's owned mutexes list and matk it
as not owned.*/
ump = ctp->p_mtxlist;
ctp->p_mtxlist = ump->m_next;
diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c
index eccf466d0..0be671c16 100644
--- a/os/kernel/src/chthreads.c
+++ b/os/kernel/src/chthreads.c
@@ -149,7 +149,7 @@ void _thread_memfill(uint8_t *startp, uint8_t *endp, uint8_t v) {
*/
Thread *chThdCreateI(void *wsp, size_t size,
tprio_t prio, tfunc_t pf, void *arg) {
- /* Thread structure is layed out in the lower part of the thread workspace */
+ /* Thread structure is layed out in the lower part of the thread workspace.*/
Thread *tp = wsp;
chDbgCheckClassI();
diff --git a/os/kernel/templates/chconf.h b/os/kernel/templates/chconf.h
index 4115636d6..b1f2cd62c 100644
--- a/os/kernel/templates/chconf.h
+++ b/os/kernel/templates/chconf.h
@@ -459,7 +459,7 @@
* @brief Threads initialization hook.
* @details User initialization code added to the @p chThdInit() API.
*
- * @note It is invoked from within @p chThdInit() and implicitily from all
+ * @note It is invoked from within @p chThdInit() and implicitly from all
* the threads creation APIs.
*/
#if !defined(THREAD_EXT_INIT_HOOK) || defined(__DOXYGEN__)
diff --git a/os/kernel/templates/chcore.c b/os/kernel/templates/chcore.c
index 8115dd0cd..2fa1a234c 100644
--- a/os/kernel/templates/chcore.c
+++ b/os/kernel/templates/chcore.c
@@ -76,7 +76,7 @@ void port_unlock_from_isr(void) {
/**
* @brief Disables all the interrupt sources.
- * @note Of course non maskable interrupt sources are not included.
+ * @note Of course non-maskable interrupt sources are not included.
*/
void port_disable(void) {
}
diff --git a/os/ports/GCC/ARM/chcore.h b/os/ports/GCC/ARM/chcore.h
index 7629aea41..47fca447e 100644
--- a/os/ports/GCC/ARM/chcore.h
+++ b/os/ports/GCC/ARM/chcore.h
@@ -379,7 +379,7 @@ struct context {
/**
* @brief Disables all the interrupt sources.
- * @note Of course non maskable interrupt sources are not included.
+ * @note Of course non-maskable interrupt sources are not included.
* @note In this port it disables both the IRQ and FIQ sources.
* @note Implements a workaround for spurious interrupts taken from the NXP
* LPC214x datasheet.
diff --git a/os/ports/GCC/ARM/rules.mk b/os/ports/GCC/ARM/rules.mk
index 78841034d..40fa8c9e2 100644
--- a/os/ports/GCC/ARM/rules.mk
+++ b/os/ports/GCC/ARM/rules.mk
@@ -28,7 +28,7 @@ else
endif
ASRC = $(ACSRC)$(ACPPSRC)
TSRC = $(TCSRC)$(TCPPSRC)
-SRCPATHS = $(sort $(dir $(ASMSRC)) $(dir $(ASRC)) $(dir $(TSRC)))
+SRCPATHS = $(sort $(dir $(ASMXSRC)) $(dir $(ASMSRC)) $(dir $(ASRC)) $(dir $(TSRC)))
# Various directories
OBJDIR = $(BUILDDIR)/obj
@@ -40,7 +40,8 @@ ACPPOBJS = $(addprefix $(OBJDIR)/, $(notdir $(ACPPSRC:.cpp=.o)))
TCOBJS = $(addprefix $(OBJDIR)/, $(notdir $(TCSRC:.c=.o)))
TCPPOBJS = $(addprefix $(OBJDIR)/, $(notdir $(TCPPSRC:.cpp=.o)))
ASMOBJS = $(addprefix $(OBJDIR)/, $(notdir $(ASMSRC:.s=.o)))
-OBJS = $(ASMOBJS) $(ACOBJS) $(TCOBJS) $(ACPPOBJS) $(TCPPOBJS)
+ASMXOBJS = $(addprefix $(OBJDIR)/, $(notdir $(ASMXSRC:.S=.o)))
+OBJS = $(ASMXOBJS) $(ASMOBJS) $(ACOBJS) $(TCOBJS) $(ACPPOBJS) $(TCPPOBJS)
# Paths
IINCDIR = $(patsubst %,-I%,$(INCDIR) $(DINCDIR) $(UINCDIR))
@@ -57,6 +58,7 @@ LIBS = $(DLIBS) $(ULIBS)
MCFLAGS = -mcpu=$(MCU)
ODFLAGS = -x --syms
ASFLAGS = $(MCFLAGS) -Wa,-amhls=$(LSTDIR)/$(notdir $(<:.s=.lst)) $(ADEFS)
+ASXFLAGS = $(MCFLAGS) -Wa,-amhls=$(LSTDIR)/$(notdir $(<:.S=.lst)) $(ADEFS)
CFLAGS = $(MCFLAGS) $(OPT) $(COPT) $(CWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.c=.lst)) $(DEFS)
CPPFLAGS = $(MCFLAGS) $(OPT) $(CPPOPT) $(CPPWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.cpp=.lst)) $(DEFS)
ifeq ($(USE_LINK_GC),yes)
@@ -162,6 +164,15 @@ else
@$(AS) -c $(ASFLAGS) -I. $(IINCDIR) $< -o $@
endif
+$(ASMXOBJS) : $(OBJDIR)/%.o : %.S Makefile
+ifeq ($(USE_VERBOSE_COMPILE),yes)
+ @echo
+ $(CC) -c $(ASXFLAGS) $(TOPT) -I. $(IINCDIR) $< -o $@
+else
+ @echo Compiling $<
+ @$(CC) -c $(ASXFLAGS) $(TOPT) -I. $(IINCDIR) $< -o $@
+endif
+
%.elf: $(OBJS) $(LDSCRIPT)
ifeq ($(USE_VERBOSE_COMPILE),yes)
@echo
diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.h b/os/ports/GCC/ARMCMx/chcore_v6m.h
index 644f73d79..84005f162 100644
--- a/os/ports/GCC/ARMCMx/chcore_v6m.h
+++ b/os/ports/GCC/ARMCMx/chcore_v6m.h
@@ -66,15 +66,13 @@
* @brief Per-thread stack overhead for interrupts servicing.
* @details This constant is used in the calculation of the correct working
* area size.
- * This value can be zero on those architecture where there is a
- * separate interrupt stack and the stack space between @p intctx and
- * @p extctx is known to be zero.
- * @note In this port it is conservatively set to 16 because the function
- * @p chSchDoReschedule() can have a stack frame, especially with
- * compiler optimizations disabled.
+ * @note In this port this value is conservatively set to 32 because the
+ * function @p chSchDoReschedule() can have a stack frame, especially
+ * with compiler optimizations disabled. The value can be reduced
+ * when compiler optimizations are enabled.
*/
#if !defined(PORT_INT_REQUIRED_STACK)
-#define PORT_INT_REQUIRED_STACK 16
+#define PORT_INT_REQUIRED_STACK 32
#endif
/**
diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.c b/os/ports/GCC/ARMCMx/chcore_v7m.c
index 13f78bb60..8c650a202 100644
--- a/os/ports/GCC/ARMCMx/chcore_v7m.c
+++ b/os/ports/GCC/ARMCMx/chcore_v7m.c
@@ -114,28 +114,6 @@ void _port_init(void) {
SCB_VTOR = CORTEX_VTOR_INIT;
SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0);
-#if CORTEX_USE_FPU
- {
- uint32_t reg;
-
- /* Initializing the FPU context save in lazy mode.*/
- SCB_FPCCR = FPCCR_ASPEN | FPCCR_LSPEN;
-
- /* CP10 and CP11 set to full access.*/
- SCB_CPACR |= 0x00F00000;
-
- /* Enables FPU context save/restore on exception entry/exit (FPCA bit).*/
- asm volatile ("mrs %0, CONTROL" : "=r" (reg) : : "memory");
- reg |= 4;
- asm volatile ("msr CONTROL, %0" : : "r" (reg) : "memory");
-
- /* FPSCR and FPDSCR initially zero.*/
- reg = 0;
- asm volatile ("vmsr FPSCR, %0" : : "r" (reg) : "memory");
- SCB_FPDSCR = reg;
- }
-#endif
-
/* Initialization of the system vectors used by the port.*/
nvicSetSystemHandlerPriority(HANDLER_SVCALL,
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL));
diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.h b/os/ports/GCC/ARMCMx/chcore_v7m.h
index e6b616dd6..10edcc45b 100644
--- a/os/ports/GCC/ARMCMx/chcore_v7m.h
+++ b/os/ports/GCC/ARMCMx/chcore_v7m.h
@@ -63,15 +63,13 @@
* @brief Per-thread stack overhead for interrupts servicing.
* @details This constant is used in the calculation of the correct working
* area size.
- * This value can be zero on those architecture where there is a
- * separate interrupt stack and the stack space between @p intctx and
- * @p extctx is known to be zero.
- * @note In this port it is conservatively set to 16 because the function
- * @p chSchDoReschedule() can have a stack frame, especially with
- * compiler optimizations disabled.
+ * @note In this port this value is conservatively set to 32 because the
+ * function @p chSchDoReschedule() can have a stack frame, especially
+ * with compiler optimizations disabled. The value can be reduced
+ * when compiler optimizations are enabled.
*/
#if !defined(PORT_INT_REQUIRED_STACK)
-#define PORT_INT_REQUIRED_STACK 16
+#define PORT_INT_REQUIRED_STACK 32
#endif
/**
@@ -414,7 +412,7 @@ struct context {
/**
* @brief Disables all the interrupt sources.
- * @note Of course non maskable interrupt sources are not included.
+ * @note Of course non-maskable interrupt sources are not included.
* @note In this port it disables all the interrupt sources by raising
* the priority mask to level 0.
*/
diff --git a/os/ports/GCC/ARMCMx/crt0.c b/os/ports/GCC/ARMCMx/crt0.c
index fbff66fb0..bb8d3830d 100644
--- a/os/ports/GCC/ARMCMx/crt0.c
+++ b/os/ports/GCC/ARMCMx/crt0.c
@@ -26,10 +26,7 @@
* @{
*/
-#include <stdint.h>
-
-#define FALSE 0
-#define TRUE (!FALSE)
+#include "ch.h"
typedef void (*funcp_t)(void);
typedef funcp_t * funcpp_t;
@@ -250,7 +247,7 @@ static void fill32(uint32_t *start, uint32_t *end, uint32_t filler) {
__attribute__((naked))
#endif
void ResetHandler(void) {
- uint32_t psp, ctl;
+ uint32_t psp, reg;
/* Process Stack initialization, it is allocated starting from the
symbol __process_stack_end__ and its lower limit is the symbol
@@ -259,9 +256,25 @@ void ResetHandler(void) {
psp = SYMVAL(__process_stack_end__);
asm volatile ("msr PSP, %0" : : "r" (psp));
+#if CORTEX_USE_FPU
+ /* Initializing the FPU context save in lazy mode.*/
+ SCB_FPCCR = FPCCR_ASPEN | FPCCR_LSPEN;
+
+ /* CP10 and CP11 set to full access.*/
+ SCB_CPACR |= 0x00F00000;
+
+ /* FPSCR and FPDSCR initially zero.*/
+ reg = 0;
+ asm volatile ("vmsr FPSCR, %0" : : "r" (reg) : "memory");
+ SCB_FPDSCR = reg;
+
+ /* CPU mode initialization, enforced FPCA bit.*/
+ reg = CRT0_CONTROL_INIT | 4;
+#else
/* CPU mode initialization.*/
- ctl = CRT0_CONTROL_INIT;
- asm volatile ("msr CONTROL, %0" : : "r" (ctl));
+ reg = CRT0_CONTROL_INIT;
+#endif
+ asm volatile ("msr CONTROL, %0" : : "r" (reg));
asm volatile ("isb");
/* Early initialization hook invocation.*/
diff --git a/os/ports/GCC/ARMCMx/rules.mk b/os/ports/GCC/ARMCMx/rules.mk
index e592683d8..111669fde 100644
--- a/os/ports/GCC/ARMCMx/rules.mk
+++ b/os/ports/GCC/ARMCMx/rules.mk
@@ -28,7 +28,7 @@ else
endif
ASRC = $(ACSRC)$(ACPPSRC)
TSRC = $(TCSRC)$(TCPPSRC)
-SRCPATHS = $(sort $(dir $(ASMSRC)) $(dir $(ASRC)) $(dir $(TSRC)))
+SRCPATHS = $(sort $(dir $(ASMXSRC)) $(dir $(ASMSRC)) $(dir $(ASRC)) $(dir $(TSRC)))
# Various directories
OBJDIR = $(BUILDDIR)/obj
@@ -40,7 +40,8 @@ ACPPOBJS = $(addprefix $(OBJDIR)/, $(notdir $(ACPPSRC:.cpp=.o)))
TCOBJS = $(addprefix $(OBJDIR)/, $(notdir $(TCSRC:.c=.o)))
TCPPOBJS = $(addprefix $(OBJDIR)/, $(notdir $(TCPPSRC:.cpp=.o)))
ASMOBJS = $(addprefix $(OBJDIR)/, $(notdir $(ASMSRC:.s=.o)))
-OBJS = $(ASMOBJS) $(ACOBJS) $(TCOBJS) $(ACPPOBJS) $(TCPPOBJS)
+ASMXOBJS = $(addprefix $(OBJDIR)/, $(notdir $(ASMXSRC:.S=.o)))
+OBJS = $(ASMXOBJS) $(ASMOBJS) $(ACOBJS) $(TCOBJS) $(ACPPOBJS) $(TCPPOBJS)
# Paths
IINCDIR = $(patsubst %,-I%,$(INCDIR) $(DINCDIR) $(UINCDIR))
@@ -57,6 +58,7 @@ LIBS = $(DLIBS) $(ULIBS)
MCFLAGS = -mcpu=$(MCU)
ODFLAGS = -x --syms
ASFLAGS = $(MCFLAGS) -Wa,-amhls=$(LSTDIR)/$(notdir $(<:.s=.lst)) $(ADEFS)
+ASXFLAGS = $(MCFLAGS) -Wa,-amhls=$(LSTDIR)/$(notdir $(<:.S=.lst)) $(ADEFS)
CFLAGS = $(MCFLAGS) $(OPT) $(COPT) $(CWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.c=.lst)) $(DEFS)
CPPFLAGS = $(MCFLAGS) $(OPT) $(CPPOPT) $(CPPWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.cpp=.lst)) $(DEFS)
ifeq ($(USE_LINK_GC),yes)
@@ -162,6 +164,15 @@ else
@$(AS) -c $(ASFLAGS) -I. $(IINCDIR) $< -o $@
endif
+$(ASMXOBJS) : $(OBJDIR)/%.o : %.S Makefile
+ifeq ($(USE_VERBOSE_COMPILE),yes)
+ @echo
+ $(CC) -c $(ASXFLAGS) $(TOPT) -I. $(IINCDIR) $< -o $@
+else
+ @echo Compiling $<
+ @$(CC) -c $(ASXFLAGS) $(TOPT) -I. $(IINCDIR) $< -o $@
+endif
+
%.elf: $(OBJS) $(LDSCRIPT)
ifeq ($(USE_VERBOSE_COMPILE),yes)
@echo
diff --git a/os/ports/GCC/AVR/chcore.h b/os/ports/GCC/AVR/chcore.h
index 18273c0d4..7f11de61b 100644
--- a/os/ports/GCC/AVR/chcore.h
+++ b/os/ports/GCC/AVR/chcore.h
@@ -274,7 +274,7 @@ struct context {
/**
* @brief Disables all the interrupt sources.
- * @note Of course non maskable interrupt sources are not included.
+ * @note Of course non-maskable interrupt sources are not included.
* @note Implemented as global interrupt disable.
*/
#define port_disable() asm volatile ("cli" : : : "memory")
diff --git a/os/ports/GCC/MSP430/chcore.h b/os/ports/GCC/MSP430/chcore.h
index 6a94f7394..d5cc1f512 100644
--- a/os/ports/GCC/MSP430/chcore.h
+++ b/os/ports/GCC/MSP430/chcore.h
@@ -247,7 +247,7 @@ struct context {
/**
* @brief Disables all the interrupt sources.
- * @note Of course non maskable interrupt sources are not included.
+ * @note Of course non-maskable interrupt sources are not included.
* @note Implemented as global interrupt disable.
*/
#define port_disable() asm volatile ("dint" : : : "memory")
diff --git a/os/ports/IAR/ARMCMx/chcore_v6m.h b/os/ports/IAR/ARMCMx/chcore_v6m.h
index 9087f3dd8..8a2ef48e5 100644
--- a/os/ports/IAR/ARMCMx/chcore_v6m.h
+++ b/os/ports/IAR/ARMCMx/chcore_v6m.h
@@ -66,15 +66,13 @@
* @brief Per-thread stack overhead for interrupts servicing.
* @details This constant is used in the calculation of the correct working
* area size.
- * This value can be zero on those architecture where there is a
- * separate interrupt stack and the stack space between @p intctx and
- * @p extctx is known to be zero.
- * @note In this port it is conservatively set to 16 because the function
- * @p chSchDoReschedule() can have a stack frame, especially with
- * compiler optimizations disabled.
+ * @note In this port this value is conservatively set to 32 because the
+ * function @p chSchDoReschedule() can have a stack frame, especially
+ * with compiler optimizations disabled. The value can be reduced
+ * when compiler optimizations are enabled.
*/
#if !defined(PORT_INT_REQUIRED_STACK)
-#define PORT_INT_REQUIRED_STACK 16
+#define PORT_INT_REQUIRED_STACK 32
#endif
/**
diff --git a/os/ports/IAR/ARMCMx/chcore_v7m.h b/os/ports/IAR/ARMCMx/chcore_v7m.h
index c8b7f67ff..b46ef22f0 100644
--- a/os/ports/IAR/ARMCMx/chcore_v7m.h
+++ b/os/ports/IAR/ARMCMx/chcore_v7m.h
@@ -63,15 +63,13 @@
* @brief Per-thread stack overhead for interrupts servicing.
* @details This constant is used in the calculation of the correct working
* area size.
- * This value can be zero on those architecture where there is a
- * separate interrupt stack and the stack space between @p intctx and
- * @p extctx is known to be zero.
- * @note In this port it is conservatively set to 16 because the function
- * @p chSchDoReschedule() can have a stack frame, especially with
- * compiler optimizations disabled.
+ * @note In this port this value is conservatively set to 32 because the
+ * function @p chSchDoReschedule() can have a stack frame, especially
+ * with compiler optimizations disabled. The value can be reduced
+ * when compiler optimizations are enabled.
*/
#if !defined(PORT_INT_REQUIRED_STACK)
-#define PORT_INT_REQUIRED_STACK 16
+#define PORT_INT_REQUIRED_STACK 32
#endif
/**
@@ -402,7 +400,7 @@ struct context {
/**
* @brief Disables all the interrupt sources.
- * @note Of course non maskable interrupt sources are not included.
+ * @note Of course non-maskable interrupt sources are not included.
* @note In this port it disables all the interrupt sources by raising
* the priority mask to level 0.
*/
diff --git a/os/ports/RC/STM8/chcore.h b/os/ports/RC/STM8/chcore.h
index e3e853467..b72f066c4 100644
--- a/os/ports/RC/STM8/chcore.h
+++ b/os/ports/RC/STM8/chcore.h
@@ -256,7 +256,7 @@ struct stm8_startctx {
/**
* @brief Disables all the interrupt sources.
* @note Implemented as global interrupts disable.
- * @note Of course non maskable interrupt sources are not included.
+ * @note Of course non-maskable interrupt sources are not included.
*/
#define port_disable() _sim_()
diff --git a/os/ports/RVCT/ARMCMx/chcore_v6m.h b/os/ports/RVCT/ARMCMx/chcore_v6m.h
index 89ab92640..5de576a21 100644
--- a/os/ports/RVCT/ARMCMx/chcore_v6m.h
+++ b/os/ports/RVCT/ARMCMx/chcore_v6m.h
@@ -66,15 +66,13 @@
* @brief Per-thread stack overhead for interrupts servicing.
* @details This constant is used in the calculation of the correct working
* area size.
- * This value can be zero on those architecture where there is a
- * separate interrupt stack and the stack space between @p intctx and
- * @p extctx is known to be zero.
- * @note In this port it is conservatively set to 16 because the function
- * @p chSchDoReschedule() can have a stack frame, especially with
- * compiler optimizations disabled.
+ * @note In this port this value is conservatively set to 32 because the
+ * function @p chSchDoReschedule() can have a stack frame, especially
+ * with compiler optimizations disabled. The value can be reduced
+ * when compiler optimizations are enabled.
*/
#if !defined(PORT_INT_REQUIRED_STACK)
-#define PORT_INT_REQUIRED_STACK 16
+#define PORT_INT_REQUIRED_STACK 32
#endif
/**
diff --git a/os/ports/RVCT/ARMCMx/chcore_v7m.h b/os/ports/RVCT/ARMCMx/chcore_v7m.h
index 6feaf3af5..98bbb6358 100644
--- a/os/ports/RVCT/ARMCMx/chcore_v7m.h
+++ b/os/ports/RVCT/ARMCMx/chcore_v7m.h
@@ -63,15 +63,13 @@
* @brief Per-thread stack overhead for interrupts servicing.
* @details This constant is used in the calculation of the correct working
* area size.
- * This value can be zero on those architecture where there is a
- * separate interrupt stack and the stack space between @p intctx and
- * @p extctx is known to be zero.
- * @note In this port it is conservatively set to 16 because the function
- * @p chSchDoReschedule() can have a stack frame, especially with
- * compiler optimizations disabled.
+ * @note In this port this value is conservatively set to 32 because the
+ * function @p chSchDoReschedule() can have a stack frame, especially
+ * with compiler optimizations disabled. The value can be reduced
+ * when compiler optimizations are enabled.
*/
#if !defined(PORT_INT_REQUIRED_STACK)
-#define PORT_INT_REQUIRED_STACK 16
+#define PORT_INT_REQUIRED_STACK 32
#endif
/**
@@ -408,7 +406,7 @@ struct context {
/**
* @brief Disables all the interrupt sources.
- * @note Of course non maskable interrupt sources are not included.
+ * @note Of course non-maskable interrupt sources are not included.
* @note In this port it disables all the interrupt sources by raising
* the priority mask to level 0.
*/
diff --git a/os/ports/cosmic/STM8/chcore.h b/os/ports/cosmic/STM8/chcore.h
index 5a06eea3a..895dc717e 100644
--- a/os/ports/cosmic/STM8/chcore.h
+++ b/os/ports/cosmic/STM8/chcore.h
@@ -253,7 +253,7 @@ struct stm8_startctx {
/**
* @brief Disables all the interrupt sources.
* @note Implemented as global interrupts disable.
- * @note Of course non maskable interrupt sources are not included.
+ * @note Of course non-maskable interrupt sources are not included.
*/
#define port_disable() _asm("sim")
diff --git a/os/various/chprintf.c b/os/various/chprintf.c
index 3936226c1..1b2c3329c 100644
--- a/os/various/chprintf.c
+++ b/os/various/chprintf.c
@@ -17,25 +17,42 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/*
+ Concepts and parts of this file have been contributed by Fabio Utzig.
+ */
#include <stdarg.h>
#include "ch.h"
+#include "chprintf.h"
#define MAX_FILLER 11
+#define FLOAT_PRECISION 100000
-static char *ltoa(char *p, long num, unsigned radix) {
+static char *long_to_string_with_divisor(char *p,
+ long num,
+ unsigned radix,
+ long divisor) {
int i;
char *q;
+ long l, ll;
+
+ l = num;
+ if (divisor == 0) {
+ ll = num;
+ } else {
+ ll = divisor;
+ }
q = p + MAX_FILLER;
do {
- i = (int)(num % radix);
+ i = (int)(l % radix);
i += '0';
if (i > '9')
i += 'A' - '0' - 10;
*--q = i;
- } while ((num /= radix) != 0);
+ l /= radix;
+ } while ((ll /= radix) != 0);
i = (int)(p + MAX_FILLER - q);
do
@@ -45,6 +62,24 @@ static char *ltoa(char *p, long num, unsigned radix) {
return p;
}
+static char *ltoa(char *p, long num, unsigned radix) {
+
+ return long_to_string_with_divisor(p, num, radix, 0);
+}
+
+#if CHPRINTF_USE_FLOAT
+static char *ftoa(char *p, double num) {
+ long l;
+ unsigned long precision = FLOAT_PRECISION;
+
+ l = num;
+ p = long_to_string_with_divisor(p, l, 10, 0);
+ *p++ = '.';
+ l = (num - l) * precision;
+ return long_to_string_with_divisor(p, l, 10, precision / 10);
+}
+#endif
+
/**
* @brief System formatted output function.
* @details This function implements a minimal @p printf() like functionality
@@ -62,8 +97,6 @@ static char *ltoa(char *p, long num, unsigned radix) {
* - <b>c</b> character.
* - <b>s</b> string.
* .
- * @note Floating point types are not implemented, this function is meant
- * as a system utility and not a full implementation.
*
* @param[in] chp pointer to a @p BaseChannel implementing object
* @param[in] fmt formatting string
@@ -75,6 +108,9 @@ void chprintf(BaseChannel *chp, const char *fmt, ...) {
int i, precision, width;
bool_t is_long, left_align;
long l;
+#if CHPRINTF_USE_FLOAT
+ float f;
+#endif
va_start(ap, fmt);
while (TRUE) {
@@ -160,6 +196,16 @@ void chprintf(BaseChannel *chp, const char *fmt, ...) {
}
p = ltoa(p, l, 10);
break;
+#if CHPRINTF_USE_FLOAT
+ case 'f':
+ f = (float) va_arg(ap, double);
+ if (f < 0) {
+ *p++ = '-';
+ f = -f;
+ }
+ p = ftoa(p, f);
+ break;
+#endif
case 'X':
case 'x':
c = 16;
diff --git a/os/various/chprintf.h b/os/various/chprintf.h
index 929da639e..866dfa067 100644
--- a/os/various/chprintf.h
+++ b/os/various/chprintf.h
@@ -29,6 +29,13 @@
#ifndef _CHPRINTF_H_
#define _CHPRINTF_H_
+/**
+ * @brief Float type support.
+ */
+#if !defined(CHPRINTF_USE_FLOAT) || defined(__DOXYGEN__)
+#define CHPRINTF_USE_FLOAT FALSE
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/os/various/chrtclib.c b/os/various/chrtclib.c
index 38f5a3627..38f5a3627 100755..100644
--- a/os/various/chrtclib.c
+++ b/os/various/chrtclib.c
diff --git a/os/various/chrtclib.h b/os/various/chrtclib.h
index 7831be83d..7831be83d 100755..100644
--- a/os/various/chrtclib.h
+++ b/os/various/chrtclib.h
diff --git a/os/various/diskio.c b/os/various/diskio.c
new file mode 100755
index 000000000..07d44db49
--- /dev/null
+++ b/os/various/diskio.c
@@ -0,0 +1,244 @@
+/*-----------------------------------------------------------------------*/
+/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */
+/*-----------------------------------------------------------------------*/
+/* This is a stub disk I/O module that acts as front end of the existing */
+/* disk I/O modules and attach it to FatFs module with common interface. */
+/*-----------------------------------------------------------------------*/
+
+#include "ch.h"
+#include "hal.h"
+
+#include "diskio.h"
+
+#if HAL_USE_MMC_SPI && HAL_USE_SDC
+#error "cannot specify both MMC_SPI and SDC drivers"
+#endif
+
+#if HAL_USE_MMC_SPI
+extern MMCDriver MMCD1;
+#elif HAL_USE_SDC
+extern SDCDriver SDCD1;
+#else
+#error "MMC_SPI or SDC driver must be specified"
+#endif
+
+#if HAL_USE_RTC
+#include "chrtclib.h"
+extern RTCDriver RTCD1;
+#endif
+
+/*-----------------------------------------------------------------------*/
+/* Correspondence between physical drive number and physical drive. */
+
+#define MMC 0
+#define SDC 0
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Inidialize a Drive */
+
+DSTATUS disk_initialize (
+ BYTE drv /* Physical drive nmuber (0..) */
+)
+{
+ DSTATUS stat;
+
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ stat = 0;
+ /* It is initialized externally, just reads the status.*/
+ if (mmcGetDriverState(&MMCD1) != MMC_READY)
+ stat |= STA_NOINIT;
+ if (mmcIsWriteProtected(&MMCD1))
+ stat |= STA_PROTECT;
+ return stat;
+#else
+ case SDC:
+ stat = 0;
+ /* It is initialized externally, just reads the status.*/
+ if (sdcGetDriverState(&SDCD1) != SDC_ACTIVE)
+ stat |= STA_NOINIT;
+ if (sdcIsWriteProtected(&SDCD1))
+ stat |= STA_PROTECT;
+ return stat;
+#endif
+ }
+ return STA_NODISK;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Return Disk Status */
+
+DSTATUS disk_status (
+ BYTE drv /* Physical drive nmuber (0..) */
+)
+{
+ DSTATUS stat;
+
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ stat = 0;
+ /* It is initialized externally, just reads the status.*/
+ if (mmcGetDriverState(&MMCD1) != MMC_READY)
+ stat |= STA_NOINIT;
+ if (mmcIsWriteProtected(&MMCD1))
+ stat |= STA_PROTECT;
+ return stat;
+#else
+ case SDC:
+ stat = 0;
+ /* It is initialized externally, just reads the status.*/
+ if (sdcGetDriverState(&SDCD1) != SDC_ACTIVE)
+ stat |= STA_NOINIT;
+ if (sdcIsWriteProtected(&SDCD1))
+ stat |= STA_PROTECT;
+ return stat;
+#endif
+ }
+ return STA_NODISK;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read Sector(s) */
+
+DRESULT disk_read (
+ BYTE drv, /* Physical drive nmuber (0..) */
+ BYTE *buff, /* Data buffer to store read data */
+ DWORD sector, /* Sector address (LBA) */
+ BYTE count /* Number of sectors to read (1..255) */
+)
+{
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ if (mmcGetDriverState(&MMCD1) != MMC_READY)
+ return RES_NOTRDY;
+ if (mmcStartSequentialRead(&MMCD1, sector))
+ return RES_ERROR;
+ while (count > 0) {
+ if (mmcSequentialRead(&MMCD1, buff))
+ return RES_ERROR;
+ buff += MMC_SECTOR_SIZE;
+ count--;
+ }
+ if (mmcStopSequentialRead(&MMCD1))
+ return RES_ERROR;
+ return RES_OK;
+#else
+ case SDC:
+ if (sdcGetDriverState(&SDCD1) != SDC_ACTIVE)
+ return RES_NOTRDY;
+ if (sdcRead(&SDCD1, sector, buff, count))
+ return RES_ERROR;
+ return RES_OK;
+#endif
+ }
+ return RES_PARERR;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Write Sector(s) */
+
+#if _READONLY == 0
+DRESULT disk_write (
+ BYTE drv, /* Physical drive nmuber (0..) */
+ const BYTE *buff, /* Data to be written */
+ DWORD sector, /* Sector address (LBA) */
+ BYTE count /* Number of sectors to write (1..255) */
+)
+{
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ if (mmcGetDriverState(&MMCD1) != MMC_READY)
+ return RES_NOTRDY;
+ if (mmcIsWriteProtected(&MMCD1))
+ return RES_WRPRT;
+ if (mmcStartSequentialWrite(&MMCD1, sector))
+ return RES_ERROR;
+ while (count > 0) {
+ if (mmcSequentialWrite(&MMCD1, buff))
+ return RES_ERROR;
+ buff += MMC_SECTOR_SIZE;
+ count--;
+ }
+ if (mmcStopSequentialWrite(&MMCD1))
+ return RES_ERROR;
+ return RES_OK;
+#else
+ case SDC:
+ if (sdcGetDriverState(&SDCD1) != SDC_ACTIVE)
+ return RES_NOTRDY;
+ if (sdcWrite(&SDCD1, sector, buff, count))
+ return RES_ERROR;
+ return RES_OK;
+#endif
+ }
+ return RES_PARERR;
+}
+#endif /* _READONLY */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Miscellaneous Functions */
+
+DRESULT disk_ioctl (
+ BYTE drv, /* Physical drive nmuber (0..) */
+ BYTE ctrl, /* Control code */
+ void *buff /* Buffer to send/receive control data */
+)
+{
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ switch (ctrl) {
+ case CTRL_SYNC:
+ return RES_OK;
+ case GET_SECTOR_SIZE:
+ *((WORD *)buff) = MMC_SECTOR_SIZE;
+ return RES_OK;
+ default:
+ return RES_PARERR;
+ }
+#else
+ case SDC:
+ switch (ctrl) {
+ case CTRL_SYNC:
+ return RES_OK;
+ case GET_SECTOR_COUNT:
+ *((DWORD *)buff) = sdcGetCardCapacity(&SDCD1);
+ return RES_OK;
+ case GET_SECTOR_SIZE:
+ *((WORD *)buff) = SDC_BLOCK_SIZE;
+ return RES_OK;
+ case GET_BLOCK_SIZE:
+ *((DWORD *)buff) = 256; /* 512b blocks in one erase block */
+ return RES_OK;
+ default:
+ return RES_PARERR;
+ }
+#endif
+ }
+ return RES_PARERR;
+}
+
+DWORD get_fattime(void) {
+#if HAL_USE_RTC
+ return rtcGetTimeFat(&RTCD1);
+#else
+ return ((uint32_t)0 | (1 << 16)) | (1 << 21); /* wrong but valid time */
+#endif
+}
+
+
+
diff --git a/os/various/evtimer.h b/os/various/evtimer.h
index 7d54d446b..695a3851e 100644
--- a/os/various/evtimer.h
+++ b/os/various/evtimer.h
@@ -29,6 +29,14 @@
#ifndef _EVTIMER_H_
#define _EVTIMER_H_
+
+/*
+ * Module dependencies check.
+ */
+#if !CH_USE_EVENTS
+#error "Event Timers require CH_USE_EVENTS"
+#endif
+
/**
* @brief Event timer structure.
*/
diff --git a/os/various/mail.c b/os/various/mail.c
new file mode 100644
index 000000000..cebd44457
--- /dev/null
+++ b/os/various/mail.c
@@ -0,0 +1,96 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file mail.c
+ * @brief Threads mail code.
+ *
+ * @addtogroup mail
+ * @{
+ */
+
+#include "ch.h"
+#include "mail.h"
+
+/**
+ * @brief Initializes a Mail Pool.
+ * @note The number of the mail objects in the mail pool should be at
+ * least <b>2+size(mailbox)<b>, this considering one writer and
+ * one reader, add one element for each extra reader or writer in
+ * order to avoid waiting on the mail pool. A smaller number of
+ * elements can be specified if waiting on the pool is acceptable.
+ *
+ * @param[out] mlp pointer to a @p MailPool structure
+ * @param[in] size the size of the mail objects to be placed in the pool
+ * @param[in] p pointer to the mail objects array first element
+ * @param[in] n number of elements in the mail objects array
+ *
+ * @init
+ */
+void mailInit(MailPool *mlp, size_t size, void *p, size_t n) {
+
+ chPoolInit(&mlp->pool, size, NULL);
+ chPoolLoadArray(&mlp->pool, p, n);
+ chSemInit(&mlp->sem, (cnt_t)n);
+}
+
+/**
+ * @brief Allocates a mail object from a mail pool.
+ * @pre The mail pool must be already been initialized.
+ *
+ * @param[in] mlp pointer to a @p MailPool structure
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The mail object.
+ * @retval NULL timeout expired.
+ *
+ * @api
+ */
+void *mailCreate(MailPool *mlp, systime_t time) {
+ msg_t msg;
+ void *mailp;
+
+ msg = chSemWaitTimeout(&mlp->sem, time);
+ if (msg != RDY_OK)
+ return NULL;
+ mailp = chPoolAlloc(&mlp->pool);
+ chDbgAssert(mailp != NULL, "mailCreate(), #1", "empty pool");
+ return mailp;
+}
+
+/**
+ * @brief Releases a mail object into a mail pool.
+ * @pre The mail pool must be already been initialized.
+ *
+ * @param[in] mlp pointer to a @p MailPool structure
+ * @param[in] mailp the pointer to the mail object to be released
+ *
+ * @api
+ */
+void mailDelete(MailPool *mlp, void *mailp) {
+
+ chPoolFree(&mlp->pool, mailp);
+ chSemSignal(&mlp->sem);
+}
+
+/** @} */
diff --git a/os/various/mail.h b/os/various/mail.h
new file mode 100644
index 000000000..1786494e6
--- /dev/null
+++ b/os/various/mail.h
@@ -0,0 +1,59 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file mail.h
+ * @brief Threads mail macros and structures.
+ *
+ * @addtogroup mail
+ * @{
+ */
+
+#ifndef _MAIL_H_
+#define _MAIL_H_
+
+/*
+ * Module dependencies check.
+ */
+#if !CH_USE_SEMAPHORES || !CH_USE_MEMPOOLS
+#error "Mail Pools require CH_USE_SEMAPHORES and CH_USE_MEMPOOLS"
+#endif
+
+/**
+ * @brief Mail Pool descriptor.
+ */
+typedef struct {
+ MemoryPool pool; /**< @brief Available mail objects. */
+ Semaphore sem; /**< @brief Semaphore guard. */
+} MailPool;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void mailInit(MailPool *mlp, size_t size, void *p, size_t n);
+ void *mailCreate(MailPool *mlp, systime_t time);
+ void mailDelete(MailPool *mlp, void *mailp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MAIL_H_ */
+
+/** @} */