aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/dox/adc.dox10
-rw-r--r--os/hal/dox/can.dox6
-rw-r--r--os/hal/dox/gpt.dox78
-rw-r--r--os/hal/dox/hal.dox24
-rw-r--r--os/hal/dox/i2c.dox8
-rw-r--r--os/hal/dox/icu.dox115
-rw-r--r--os/hal/dox/mac.dox7
-rw-r--r--os/hal/dox/mmc_spi.dox5
-rw-r--r--os/hal/dox/pal.dox29
-rw-r--r--os/hal/dox/pwm.dox13
-rw-r--r--os/hal/dox/sdc.dox109
-rw-r--r--os/hal/dox/serial.dox43
-rw-r--r--os/hal/dox/serial_usb.dox56
-rw-r--r--os/hal/dox/spi.dox9
-rw-r--r--os/hal/dox/uart.dox44
-rw-r--r--os/hal/dox/usb.dox239
-rw-r--r--os/hal/hal.dox6
-rw-r--r--os/hal/hal.mk3
-rw-r--r--os/hal/include/adc.h61
-rw-r--r--os/hal/include/can.h5
-rw-r--r--os/hal/include/gpt.h105
-rw-r--r--os/hal/include/hal.h6
-rw-r--r--os/hal/include/i2c.h3
-rw-r--r--os/hal/include/icu.h169
-rw-r--r--os/hal/include/mac.h5
-rw-r--r--os/hal/include/mii.h8
-rw-r--r--os/hal/include/mmc_spi.h31
-rw-r--r--os/hal/include/pal.h34
-rw-r--r--os/hal/include/pwm.h129
-rw-r--r--os/hal/include/sdc.h234
-rw-r--r--os/hal/include/serial.h3
-rw-r--r--os/hal/include/serial_usb.h34
-rw-r--r--os/hal/include/spi.h33
-rw-r--r--os/hal/include/uart.h3
-rw-r--r--os/hal/include/usb.h286
-rw-r--r--os/hal/include/usb_cdc.h66
-rw-r--r--os/hal/platforms/AT91SAM7/at91sam7.h3
-rw-r--r--os/hal/platforms/AT91SAM7/at91sam7_mii.c3
-rw-r--r--os/hal/platforms/AT91SAM7/at91sam7_mii.h3
-rw-r--r--os/hal/platforms/AT91SAM7/hal_lld.c3
-rw-r--r--os/hal/platforms/AT91SAM7/hal_lld.h3
-rw-r--r--os/hal/platforms/AT91SAM7/mac_lld.c47
-rw-r--r--os/hal/platforms/AT91SAM7/mac_lld.h28
-rw-r--r--os/hal/platforms/AT91SAM7/pal_lld.c3
-rw-r--r--os/hal/platforms/AT91SAM7/pal_lld.h24
-rw-r--r--os/hal/platforms/AT91SAM7/platform.dox47
-rw-r--r--os/hal/platforms/AT91SAM7/serial_lld.c7
-rw-r--r--os/hal/platforms/AT91SAM7/serial_lld.h3
-rw-r--r--os/hal/platforms/AT91SAM7/spi_lld.c97
-rw-r--r--os/hal/platforms/AT91SAM7/spi_lld.h23
-rw-r--r--os/hal/platforms/AVR/hal_lld.c3
-rw-r--r--os/hal/platforms/AVR/hal_lld.h3
-rw-r--r--os/hal/platforms/AVR/platform.dox5
-rw-r--r--os/hal/platforms/AVR/serial_lld.c13
-rw-r--r--os/hal/platforms/AVR/serial_lld.h5
-rw-r--r--os/hal/platforms/LPC11xx/core_cm0.h3
-rw-r--r--os/hal/platforms/LPC11xx/gpt_lld.c342
-rw-r--r--os/hal/platforms/LPC11xx/gpt_lld.h208
-rw-r--r--os/hal/platforms/LPC11xx/hal_lld.c3
-rw-r--r--os/hal/platforms/LPC11xx/hal_lld.h3
-rw-r--r--os/hal/platforms/LPC11xx/pal_lld.c3
-rw-r--r--os/hal/platforms/LPC11xx/pal_lld.h3
-rw-r--r--os/hal/platforms/LPC11xx/platform.dox63
-rw-r--r--os/hal/platforms/LPC11xx/platform.mk1
-rw-r--r--os/hal/platforms/LPC11xx/serial_lld.c3
-rw-r--r--os/hal/platforms/LPC11xx/serial_lld.h3
-rw-r--r--os/hal/platforms/LPC11xx/spi_lld.c105
-rw-r--r--os/hal/platforms/LPC11xx/spi_lld.h37
-rw-r--r--os/hal/platforms/LPC13xx/core_cm3.h3
-rw-r--r--os/hal/platforms/LPC13xx/gpt_lld.c342
-rw-r--r--os/hal/platforms/LPC13xx/gpt_lld.h212
-rw-r--r--os/hal/platforms/LPC13xx/hal_lld.c3
-rw-r--r--os/hal/platforms/LPC13xx/hal_lld.h3
-rw-r--r--os/hal/platforms/LPC13xx/pal_lld.c3
-rw-r--r--os/hal/platforms/LPC13xx/pal_lld.h3
-rw-r--r--os/hal/platforms/LPC13xx/platform.dox63
-rw-r--r--os/hal/platforms/LPC13xx/platform.mk1
-rw-r--r--os/hal/platforms/LPC13xx/serial_lld.c3
-rw-r--r--os/hal/platforms/LPC13xx/serial_lld.h3
-rw-r--r--os/hal/platforms/LPC13xx/spi_lld.c103
-rw-r--r--os/hal/platforms/LPC13xx/spi_lld.h35
-rw-r--r--os/hal/platforms/LPC214x/hal_lld.c3
-rw-r--r--os/hal/platforms/LPC214x/hal_lld.h3
-rw-r--r--os/hal/platforms/LPC214x/lpc214x.h3
-rw-r--r--os/hal/platforms/LPC214x/pal_lld.c3
-rw-r--r--os/hal/platforms/LPC214x/pal_lld.h16
-rw-r--r--os/hal/platforms/LPC214x/platform.dox45
-rw-r--r--os/hal/platforms/LPC214x/serial_lld.c3
-rw-r--r--os/hal/platforms/LPC214x/serial_lld.h3
-rw-r--r--os/hal/platforms/LPC214x/spi_lld.c99
-rw-r--r--os/hal/platforms/LPC214x/spi_lld.h37
-rw-r--r--os/hal/platforms/LPC214x/vic.c3
-rw-r--r--os/hal/platforms/LPC214x/vic.h3
-rw-r--r--os/hal/platforms/MSP430/hal_lld.c3
-rw-r--r--os/hal/platforms/MSP430/hal_lld.h3
-rw-r--r--os/hal/platforms/MSP430/pal_lld.c3
-rw-r--r--os/hal/platforms/MSP430/pal_lld.h7
-rw-r--r--os/hal/platforms/MSP430/platform.dox7
-rw-r--r--os/hal/platforms/MSP430/serial_lld.c5
-rw-r--r--os/hal/platforms/MSP430/serial_lld.h3
-rw-r--r--os/hal/platforms/Posix/console.c3
-rw-r--r--os/hal/platforms/Posix/console.h3
-rw-r--r--os/hal/platforms/Posix/hal_lld.c3
-rw-r--r--os/hal/platforms/Posix/hal_lld.h3
-rw-r--r--os/hal/platforms/Posix/pal_lld.c3
-rw-r--r--os/hal/platforms/Posix/pal_lld.h12
-rw-r--r--os/hal/platforms/Posix/serial_lld.c3
-rw-r--r--os/hal/platforms/Posix/serial_lld.h3
-rw-r--r--os/hal/platforms/SPC56x/hal_lld.c3
-rw-r--r--os/hal/platforms/SPC56x/hal_lld.h7
-rw-r--r--os/hal/platforms/SPC56x/platform.dox5
-rw-r--r--os/hal/platforms/SPC56x/serial_lld.c3
-rw-r--r--os/hal/platforms/SPC56x/serial_lld.h3
-rw-r--r--os/hal/platforms/SPC56x/typedefs.h3
-rw-r--r--os/hal/platforms/STM32/adc_lld.c104
-rw-r--r--os/hal/platforms/STM32/adc_lld.h61
-rw-r--r--os/hal/platforms/STM32/can_lld.c143
-rw-r--r--os/hal/platforms/STM32/can_lld.h83
-rw-r--r--os/hal/platforms/STM32/core_cm3.h3
-rw-r--r--os/hal/platforms/STM32/gpt_lld.c417
-rw-r--r--os/hal/platforms/STM32/gpt_lld.h256
-rw-r--r--os/hal/platforms/STM32/hal_lld.c68
-rw-r--r--os/hal/platforms/STM32/hal_lld.h7
-rw-r--r--os/hal/platforms/STM32/hal_lld_f100.h3
-rw-r--r--os/hal/platforms/STM32/hal_lld_f103.h13
-rw-r--r--os/hal/platforms/STM32/hal_lld_f105_f107.h142
-rw-r--r--os/hal/platforms/STM32/icu_lld.c425
-rw-r--r--os/hal/platforms/STM32/icu_lld.h290
-rw-r--r--os/hal/platforms/STM32/pal_lld.c18
-rw-r--r--os/hal/platforms/STM32/pal_lld.h10
-rw-r--r--os/hal/platforms/STM32/platform.dox116
-rw-r--r--os/hal/platforms/STM32/platform.mk3
-rw-r--r--os/hal/platforms/STM32/pwm_lld.c249
-rw-r--r--os/hal/platforms/STM32/pwm_lld.h238
-rw-r--r--os/hal/platforms/STM32/sdc_lld.c722
-rw-r--r--os/hal/platforms/STM32/sdc_lld.h203
-rw-r--r--os/hal/platforms/STM32/serial_lld.c3
-rw-r--r--os/hal/platforms/STM32/serial_lld.h3
-rw-r--r--os/hal/platforms/STM32/spi_lld.c269
-rw-r--r--os/hal/platforms/STM32/spi_lld.h67
-rw-r--r--os/hal/platforms/STM32/stm32_dma.c398
-rw-r--r--os/hal/platforms/STM32/stm32_dma.h48
-rw-r--r--os/hal/platforms/STM32/stm32_usb.h10
-rw-r--r--os/hal/platforms/STM32/stm32f10x.h485
-rw-r--r--os/hal/platforms/STM32/uart_lld.c385
-rw-r--r--os/hal/platforms/STM32/uart_lld.h89
-rw-r--r--os/hal/platforms/STM32/usb_lld.c517
-rw-r--r--os/hal/platforms/STM32/usb_lld.h236
-rw-r--r--os/hal/platforms/STM8L/hal_lld.c3
-rw-r--r--os/hal/platforms/STM8L/hal_lld.h3
-rw-r--r--os/hal/platforms/STM8L/hal_lld_stm8l_hd.h3
-rw-r--r--os/hal/platforms/STM8L/hal_lld_stm8l_md.h3
-rw-r--r--os/hal/platforms/STM8L/hal_lld_stm8l_mdp.h3
-rw-r--r--os/hal/platforms/STM8L/pal_lld.c3
-rw-r--r--os/hal/platforms/STM8L/pal_lld.h8
-rw-r--r--os/hal/platforms/STM8L/platform.dox7
-rw-r--r--os/hal/platforms/STM8L/serial_lld.c3
-rw-r--r--os/hal/platforms/STM8L/serial_lld.h15
-rw-r--r--os/hal/platforms/STM8L/shared_isr.c3
-rw-r--r--os/hal/platforms/STM8S/hal_lld.c3
-rw-r--r--os/hal/platforms/STM8S/hal_lld.h5
-rw-r--r--os/hal/platforms/STM8S/pal_lld.c3
-rw-r--r--os/hal/platforms/STM8S/pal_lld.h8
-rw-r--r--os/hal/platforms/STM8S/platform.dox45
-rw-r--r--os/hal/platforms/STM8S/serial_lld.c5
-rw-r--r--os/hal/platforms/STM8S/serial_lld.h3
-rw-r--r--os/hal/platforms/STM8S/spi_lld.c49
-rw-r--r--os/hal/platforms/STM8S/spi_lld.h31
-rw-r--r--os/hal/platforms/Win32/console.c3
-rw-r--r--os/hal/platforms/Win32/console.h3
-rw-r--r--os/hal/platforms/Win32/hal_lld.c3
-rw-r--r--os/hal/platforms/Win32/hal_lld.h3
-rw-r--r--os/hal/platforms/Win32/pal_lld.c3
-rw-r--r--os/hal/platforms/Win32/pal_lld.h12
-rw-r--r--os/hal/platforms/Win32/serial_lld.c3
-rw-r--r--os/hal/platforms/Win32/serial_lld.h3
-rw-r--r--os/hal/platforms/platforms.dox3
-rw-r--r--os/hal/src/adc.c81
-rw-r--r--os/hal/src/can.c83
-rw-r--r--os/hal/src/gpt.c229
-rw-r--r--os/hal/src/hal.c12
-rw-r--r--os/hal/src/i2c.c3
-rw-r--r--os/hal/src/icu.c151
-rw-r--r--os/hal/src/mac.c17
-rw-r--r--os/hal/src/mmc_spi.c202
-rw-r--r--os/hal/src/pal.c15
-rw-r--r--os/hal/src/pwm.c62
-rw-r--r--os/hal/src/sdc.c392
-rw-r--r--os/hal/src/serial.c3
-rw-r--r--os/hal/src/serial_usb.c107
-rw-r--r--os/hal/src/spi.c80
-rw-r--r--os/hal/src/uart.c100
-rw-r--r--os/hal/src/usb.c547
-rw-r--r--os/hal/templates/adc_lld.c7
-rw-r--r--os/hal/templates/adc_lld.h25
-rw-r--r--os/hal/templates/can_lld.c5
-rw-r--r--os/hal/templates/can_lld.h55
-rw-r--r--os/hal/templates/gpt_lld.c135
-rw-r--r--os/hal/templates/gpt_lld.h134
-rw-r--r--os/hal/templates/hal_lld.c3
-rw-r--r--os/hal/templates/hal_lld.h3
-rw-r--r--os/hal/templates/halconf.h68
-rw-r--r--os/hal/templates/i2c_lld.c3
-rw-r--r--os/hal/templates/i2c_lld.h3
-rw-r--r--os/hal/templates/icu_lld.c145
-rw-r--r--os/hal/templates/icu_lld.h138
-rw-r--r--os/hal/templates/mac_lld.c3
-rw-r--r--os/hal/templates/mac_lld.h17
-rw-r--r--os/hal/templates/meta/driver.c23
-rw-r--r--os/hal/templates/meta/driver.h3
-rw-r--r--os/hal/templates/meta/driver_lld.c9
-rw-r--r--os/hal/templates/meta/driver_lld.h7
-rw-r--r--os/hal/templates/pal_lld.c3
-rw-r--r--os/hal/templates/pal_lld.h3
-rw-r--r--os/hal/templates/pwm_lld.c38
-rw-r--r--os/hal/templates/pwm_lld.h98
-rw-r--r--os/hal/templates/serial_lld.c3
-rw-r--r--os/hal/templates/serial_lld.h3
-rw-r--r--os/hal/templates/spi_lld.c5
-rw-r--r--os/hal/templates/spi_lld.h19
-rw-r--r--os/hal/templates/uart_lld.c3
-rw-r--r--os/hal/templates/uart_lld.h21
-rw-r--r--os/hal/templates/usb_lld.c346
-rw-r--r--os/hal/templates/usb_lld.h310
224 files changed, 11124 insertions, 3129 deletions
diff --git a/os/hal/dox/adc.dox b/os/hal/dox/adc.dox
index 9ebfca99c..bb8ff014f 100644
--- a/os/hal/dox/adc.dox
+++ b/os/hal/dox/adc.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -20,7 +21,8 @@
/**
* @defgroup ADC ADC Driver
* @brief Generic ADC Driver.
- * @details This module implements a generic ADC driver.
+ * @details This module implements a generic ADC (Analog to Digital Converter)
+ * driver supporting a variety of buffer and conversion modes.
* @pre In order to use the ADC driver the @p HAL_USE_ADC option
* must be enabled in @p halconf.h.
*
@@ -52,7 +54,7 @@
active -> ready [label="\nadcStopConversion()\nsync return"];
active -> active [label="\nasync callback (half buffer)\nasync callback (full buffer circular)\n>acg_endcb<"];
active -> complete [label="\nasync callback (full buffer)\n>acg_endcb<"];
- complete -> active [label="\nadcStartConversionI()\nthen\ncallback return()"];
+ complete -> active [label="\nadcStartConversionI()\nthen\ncallback return"];
complete -> ready [label="\ncallback return"];
}
* @enddot
@@ -78,7 +80,7 @@
active -> ready [label="\nadcStopConversion()\nsync return"];
active -> active [label="\nasync callback (half buffer)\nasync callback (full buffer circular)\n>acg_endcb<"];
active -> complete [label="\nasync callback (full buffer)\n>acg_endcb<"];
- complete -> active [label="\nadcStartConversionI()\nthen\ncallback return()"];
+ complete -> active [label="\nadcStartConversionI()\nthen\ncallback return"];
complete -> ready [label="\ncallback return"];
}
* @enddot
diff --git a/os/hal/dox/can.dox b/os/hal/dox/can.dox
index 81ee24e8b..1a0c81c0d 100644
--- a/os/hal/dox/can.dox
+++ b/os/hal/dox/can.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -20,7 +21,8 @@
/**
* @defgroup CAN CAN Driver
* @brief Generic CAN Driver.
- * @details This module implements a generic CAN driver.
+ * @details This module implements a generic CAN (Controller Area Network)
+ * driver allowing the exchange of information at frame level.
* @pre In order to use the CAN driver the @p HAL_USE_CAN option
* must be enabled in @p halconf.h.
*
diff --git a/os/hal/dox/gpt.dox b/os/hal/dox/gpt.dox
new file mode 100644
index 000000000..d51ad6af3
--- /dev/null
+++ b/os/hal/dox/gpt.dox
@@ -0,0 +1,78 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/>.
+*/
+
+/**
+ * @defgroup GPT GPT Driver
+ * @brief Generic GPT Driver.
+ * @details This module implements a generic GPT (General Purpose Timer)
+ * driver. The timer can be programmed in order to trigger callbacks
+ * after a specified time period or continuously with a specified
+ * interval.
+ * @pre In order to use the GPT driver the @p HAL_USE_GPT option
+ * must be enabled in @p halconf.h.
+ *
+ * @section gpt_1 Driver State Machine
+ * The driver implements a state machine internally, not all the driver
+ * functionalities can be used in any moment, any transition not explicitly
+ * shown in the following diagram has to be considered an error and shall
+ * be captured by an assertion (if enabled).
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ stop [label="GPT_STOP\nLow Power"];
+ uninit [label="GPT_UNINIT", style="bold"];
+ ready [label="GPT_READY\nClock Enabled"];
+ continuous [label="GPT_CONT..S\nContinuous\nMode"];
+ oneshot [label="GPT_ONESHOT\nOne Shot\nMode"];
+
+ uninit -> stop [label=" gptInit()", constraint=false];
+ stop -> stop [label="\ngptStop()"];
+ stop -> ready [label="\ngptStart()"];
+ ready -> stop [label="\ngptStop()"];
+ ready -> ready [label="\ngptStart()"];
+ ready -> continuous [label="\ngptStartContinuous()"];
+ continuous -> ready [label="\ngptStopTimer()"];
+ continuous -> continuous [label=">callback<"];
+ ready -> oneshot [label="\ngptStartOneShot()\ngptPolledDelay()"];
+ oneshot -> ready [label="\n>callback<\nor\nDelay Over"];
+ }
+ * @enddot
+ *
+ * @section gpt_2 GPT Operations.
+ * This driver abstracts a generic timer composed of:
+ * - A clock prescaler.
+ * - A main up counter.
+ * - A comparator register that resets the main counter to zero when the limit
+ * is reached. A callback is invoked when this happens.
+ * .
+ * The timer can operate in three different modes:
+ * - <b>Continuous Mode</b>, a periodic callback is invoked until the driver
+ * is explicitly stopped.
+ * - <b>One Shot Mode</b>, a callback is invoked after the programmed period
+ * and then the timer automatically stops.
+ * - <b>Delay Mode</b>, the timer is used for inserting a brief delay into
+ * the execution flow, no callback is invoked in this mode.
+ * .
+ * @ingroup IO
+ */
diff --git a/os/hal/dox/hal.dox b/os/hal/dox/hal.dox
index 02d09c0d8..15b4401fb 100644
--- a/os/hal/dox/hal.dox
+++ b/os/hal/dox/hal.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,16 +20,17 @@
/**
* @defgroup HAL HAL Driver
- * @brief Hardware Abstraction Layer.
- * @details The HAL driver performs the system initialization and includes
- * the platform support code shared by the other drivers. This driver does
- * contain any API function except for a general initialization function
- * @p halInit() that must be invoked before any HAL service can be used,
- * usually the HAL initialization should be performed immediately before the
- * kernel initialization.<br>
- * Some HAL driver implementations also offer a custom early clock
- * setum function that can be invoked before the C runtime initialization
- * in order to accellerate the startup time.
+ * @brief Hardware Abstraction Layer.
+ * @details The HAL (Hardware Abstraction Layer) driver performs the system
+ * initialization and includes the platform support code shared by
+ * the other drivers. This driver does contain any API function
+ * except for a general initialization function @p halInit() that
+ * must be invoked before any HAL service can be used, usually the
+ * HAL initialization should be performed immediately before the
+ * kernel initialization.<br>
+ * Some HAL driver implementations also offer a custom early clock
+ * setup function that can be invoked before the C runtime
+ * initialization in order to accelerate the startup time.
*
* @ingroup IO
*/
diff --git a/os/hal/dox/i2c.dox b/os/hal/dox/i2c.dox
index 151c7a66e..1ffd2da47 100644
--- a/os/hal/dox/i2c.dox
+++ b/os/hal/dox/i2c.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,8 +20,9 @@
/**
* @defgroup I2C I2C Driver
- * @brief Generic I2C Driver.
- * @details This module implements a generic I2C driver.
+ * @brief Generic I2C Driver.
+ * @details This module implements a generic I2C (Inter-Integrated Circuit)
+ * driver.
* @pre In order to use the I2C driver the @p HAL_USE_I2C option
* must be enabled in @p halconf.h.
*
diff --git a/os/hal/dox/icu.dox b/os/hal/dox/icu.dox
new file mode 100644
index 000000000..c90dc237d
--- /dev/null
+++ b/os/hal/dox/icu.dox
@@ -0,0 +1,115 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/>.
+*/
+
+/**
+ * @defgroup ICU ICU Driver
+ * @brief Generic ICU Driver.
+ * @details This module implements a generic ICU (Input Capture Unit) driver.
+ * @pre In order to use the ICU driver the @p HAL_USE_ICU option
+ * must be enabled in @p halconf.h.
+ *
+ * @section icu_1 Driver State Machine
+ * The driver implements a state machine internally, not all the driver
+ * functionalities can be used in any moment, any transition not explicitly
+ * shown in the following diagram has to be considered an error and shall
+ * be captured by an assertion (if enabled).
+ * @if LATEX_PDF
+ * @dot
+ digraph example {
+ size="5, 7";
+ rankdir="LR";
+
+ node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
+ edge [fontname=Sans, fontsize=8];
+
+ stop [label="ICU_STOP\nLow Power"];
+ uninit [label="ICU_UNINIT", style="bold"];
+ ready [label="ICU_READY\nClock Enabled"];
+ waiting [label="ICU_WAITING"];
+ active [label="ICU_ACTIVE"];
+ idle [label="ICU_IDLE"];
+
+ uninit -> stop [label=" icuInit()", constraint=false];
+ stop -> stop [label="\nicuStop()"];
+ stop -> ready [label="\nicuStart()"];
+ ready -> stop [label="\nicuStop()"];
+ ready -> ready [label="\nicuStart()\nicuDisable()"];
+ ready -> waiting [label="\nicuEnable()"];
+ waiting -> active [label="\nStart Front"];
+ waiting -> ready [label="\nicuDisable()"];
+ active -> idle [label="\nStop Front\n>width_cb<"];
+ active -> ready [label="\nicuDisable()\nicuDisableI()"];
+ idle -> active [label="\nStart Front\n>period_cb<"];
+ idle -> ready [label="\nicuDisable()\nicuDisableI()"];
+ }
+ * @enddot
+ * @else
+ * @dot
+ digraph example {
+ rankdir="LR";
+
+ node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
+ edge [fontname=Sans, fontsize=8];
+
+ stop [label="ICU_STOP\nLow Power"];
+ uninit [label="ICU_UNINIT", style="bold"];
+ ready [label="ICU_READY\nClock Enabled"];
+ waiting [label="ICU_WAITING"];
+ active [label="ICU_ACTIVE"];
+ idle [label="ICU_IDLE"];
+
+ uninit -> stop [label=" icuInit()", constraint=false];
+ stop -> stop [label="\nicuStop()"];
+ stop -> ready [label="\nicuStart()"];
+ ready -> stop [label="\nicuStop()"];
+ ready -> ready [label="\nicuStart()\nicuDisable()"];
+ ready -> waiting [label="\nicuEnable()"];
+ waiting -> active [label="\nStart Front"];
+ waiting -> ready [label="\nicuDisable()"];
+ active -> idle [label="\nStop Front\n>width_cb<"];
+ active -> ready [label="\nicuDisable()\nicuDisableI()"];
+ idle -> active [label="\nStart Front\n>period_cb<"];
+ idle -> ready [label="\nicuDisable()\nicuDisableI()"];
+ }
+ * @enddot
+ * @endif
+ *
+ * @section icu_2 ICU Operations.
+ * This driver abstracts a generic Input Capture Unit composed of:
+ * - A clock prescaler.
+ * - A main up counter.
+ * - Two capture registers triggered by the rising and falling edges on
+ * the sampled input.
+ * .
+ * The ICU unit can be programmed to synchronize on the rising or falling
+ * edge of the sample input:
+ * - <b>ICU_INPUT_ACTIVE_HIGH</b>, a rising edge is the start signal.
+ * - <b>ICU_INPUT_ACTIVE_LOW</b>, a falling edge is the start signal.
+ * .
+ * After the activation the ICU unit can be in one of the following
+ * states at any time:
+ * - <b>ICU_WAITING</b>, waiting the first start signal.
+ * - <b>ICU_ACTIVE</b>, after a start signal.
+ * - <b>ICU_IDLE</b>, after a stop signal.
+ * .
+ * Callbacks are invoked when start or stop signals occur.
+ *
+ * @ingroup IO
+ */
diff --git a/os/hal/dox/mac.dox b/os/hal/dox/mac.dox
index 778795f15..01a89d825 100644
--- a/os/hal/dox/mac.dox
+++ b/os/hal/dox/mac.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -20,8 +21,8 @@
/**
* @defgroup MAC MAC Driver
* @brief Generic MAC driver.
- * @details This module implements a generic interface for MAC (Media
- * Access Control) drivers, as example Ethernet controllers.
+ * @details This module implements a generic MAC (Media Access Control)
+ * driver for Ethernet controllers.
* @pre In order to use the MAC driver the @p HAL_USE_MAC option
* must be enabled in @p halconf.h.
*
diff --git a/os/hal/dox/mmc_spi.dox b/os/hal/dox/mmc_spi.dox
index e18ff1a8a..480240c00 100644
--- a/os/hal/dox/mmc_spi.dox
+++ b/os/hal/dox/mmc_spi.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -20,7 +21,7 @@
/**
* @defgroup MMC_SPI MMC over SPI Driver
* @brief Generic MMC driver.
- * @details This module implements a portable MMC driver that uses a SPI
+ * @details This module implements a portable MMC/SD driver that uses a SPI
* driver as physical layer.
* @pre In order to use the MMC_SPI driver the @p HAL_USE_MMC_SPI option
* must be enabled in @p halconf.h.
diff --git a/os/hal/dox/pal.dox b/os/hal/dox/pal.dox
index 4c7fe685a..5ffc763a8 100644
--- a/os/hal/dox/pal.dox
+++ b/os/hal/dox/pal.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,19 +20,21 @@
/**
* @defgroup PAL PAL Driver
- * @brief I/O Ports Abstraction Layer
+ * @brief I/O Ports Abstraction Layer
* @details This module defines an abstract interface for digital I/O ports.
- * Note that most I/O ports functions are just macros. The macros
- * have default software implementations that can be redefined in a
- * PAL Low Level Driver if the target hardware supports special features like,
- * as example, atomic bit set/reset/masking. Please refer to the ports specific
- * documentation for details.<br>
- * The @ref PAL has the advantage to make the access to the I/O ports platform
- * independent and still be optimized for the specific architectures.<br>
- * Note that the PAL Low Level Driver may also offer non standard macro and
- * functions in order to support specific features but, of course, the use of
- * such interfaces would not be portable. Such interfaces shall be marked with
- * the architecture name inside the function names.
+ * Note that most I/O ports functions are just macros. The macros
+ * have default software implementations that can be redefined in a
+ * PAL Low Level Driver if the target hardware supports special
+ * features like, for example, atomic bit set/reset/masking. Please
+ * refer to the ports specific documentation for details.<br>
+ * The @ref PAL has the advantage to make the access to the I/O
+ * ports platform independent and still be optimized for the specific
+ * architectures.<br>
+ * Note that the PAL Low Level Driver may also offer non standard
+ * macro and functions in order to support specific features but,
+ * of course, the use of such interfaces would not be portable.
+ * Such interfaces shall be marked with the architecture name inside
+ * the function names.
* @pre In order to use the PAL driver the @p HAL_USE_PAL option
* must be enabled in @p halconf.h.
*
diff --git a/os/hal/dox/pwm.dox b/os/hal/dox/pwm.dox
index 6fbe2efa1..fbf61ca9f 100644
--- a/os/hal/dox/pwm.dox
+++ b/os/hal/dox/pwm.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,8 +20,9 @@
/**
* @defgroup PWM PWM Driver
- * @brief Generic PWM Driver.
- * @details This module implements a generic PWM driver.
+ * @brief Generic PWM Driver.
+ * @details This module implements a generic PWM (Pulse Width Modulation)
+ * driver.
* @pre In order to use the PWM driver the @p HAL_USE_PWM option
* must be enabled in @p halconf.h.
*
@@ -45,8 +47,9 @@
}
* @enddot
*
- * @section pwm_1 PWM Operations.
- * This driver abstracts a generic PWM times composed of:
+ * @section pwm_2 PWM Operations.
+ * This driver abstracts a generic PWM timer composed of:
+ * - A clock prescaler.
* - A main up counter.
* - A comparator register that resets the main counter to zero when the limit
* is reached. An optional callback can be generated when this happens.
diff --git a/os/hal/dox/sdc.dox b/os/hal/dox/sdc.dox
new file mode 100644
index 000000000..df88796af
--- /dev/null
+++ b/os/hal/dox/sdc.dox
@@ -0,0 +1,109 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/>.
+*/
+
+/**
+ * @defgroup SDC SDC Driver
+ * @brief Generic SD Card Driver.
+ * @details This module implements a generic SDC (Secure Digital Card) driver.
+ * @pre In order to use the SDC driver the @p HAL_USE_SDC option
+ * must be enabled in @p halconf.h.
+ *
+ * @section sdc_1 Driver State Machine
+ * The driver implements a state machine internally, not all the driver
+ * functionalities can be used in any moment, any transition not explicitly
+ * shown in the following diagram has to be considered an error and shall
+ * be captured by an assertion (if enabled).
+ * @if LATEX_PDF
+ * @dot
+ digraph example {
+ size="5, 7";
+ rankdir="LR";
+
+ node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
+ edge [fontname=Sans, fontsize=8];
+
+ stop [label="SDC_STOP\nLow Power"];
+ uninit [label="SDC_UNINIT", style="bold"];
+ ready [label="SDC_READY\nClock Enabled"];
+ connecting [label="SDC_CONN.ING\nConnecting"];
+ disconnecting [label="SDC_DISC.ING\nDisconnecting"];
+ active [label="SDC_ACTIVE\nCard Ready"];
+ reading [label="SDC_READING\nReading"];
+ writing [label="SDC_WRITING\nWriting"];
+
+ uninit -> stop [label=" sdcInit()", constraint=false];
+ stop -> stop [label="\nsdcStop()"];
+ stop -> ready [label="\nsdcStart()"];
+ ready -> stop [label="\nsdcStop()"];
+ ready -> ready [label="\nsdcStart()\nsdcDisconnect()"];
+ ready -> connecting [label="\nsdcConnect()"];
+ connecting -> active [label="\nconnection\nsuccessful"];
+ connecting -> active [label="\nsdcConnect()", dir="back"];
+ connecting -> ready [label="\nconnection\nfailed"];
+ disconnecting -> active [label="\nsdcDisconnect()", dir="back"];
+ ready -> disconnecting [label="\ndisconnection\nfinished", dir="back"];
+ active -> reading [label="\nsdcRead()"];
+ reading -> active [label="\nread finished\nread error"];
+ active -> writing [label="\nsdcWrite()"];
+ writing -> active [label="\nwrite finished\nwrite error"];
+ }
+ * @enddot
+ * @else
+ * @dot
+ digraph example {
+ rankdir="LR";
+
+ node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
+ edge [fontname=Sans, fontsize=8];
+
+ stop [label="SDC_STOP\nLow Power"];
+ uninit [label="SDC_UNINIT", style="bold"];
+ ready [label="SDC_READY\nClock Enabled"];
+ connecting [label="SDC_CONN.ING\nConnecting"];
+ disconnecting [label="SDC_DISC.ING\nDisconnecting"];
+ active [label="SDC_ACTIVE\nCard Ready"];
+ reading [label="SDC_READING\nReading"];
+ writing [label="SDC_WRITING\nWriting"];
+
+ uninit -> stop [label=" sdcInit()", constraint=false];
+ stop -> stop [label="\nsdcStop()"];
+ stop -> ready [label="\nsdcStart()"];
+ ready -> stop [label="\nsdcStop()"];
+ ready -> ready [label="\nsdcStart()\nsdcDisconnect()"];
+ ready -> connecting [label="\nsdcConnect()"];
+ connecting -> active [label="\nconnection\nsuccessful"];
+ connecting -> active [label="\nsdcConnect()", dir="back"];
+ connecting -> ready [label="\nconnection\nfailed"];
+ disconnecting -> active [label="\nsdcDisconnect()", dir="back"];
+ ready -> disconnecting [label="\ndisconnection\nfinished", dir="back"];
+ active -> reading [label="\nsdcRead()"];
+ reading -> active [label="\nread finished\nread error"];
+ active -> writing [label="\nsdcWrite()"];
+ writing -> active [label="\nwrite finished\nwrite error"];
+ }
+ * @enddot
+ * @endif
+ *
+ * @section sdc_2 SDC Operations.
+ * This driver allows to read or write single or multiple 512 bytes blocks
+ * on a SD Card.
+ *
+ * @ingroup IO
+ */
diff --git a/os/hal/dox/serial.dox b/os/hal/dox/serial.dox
index 071b2dac5..5b68f9c9c 100644
--- a/os/hal/dox/serial.dox
+++ b/os/hal/dox/serial.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,16 +20,42 @@
/**
* @defgroup SERIAL Serial Driver
- * @brief Generic Serial Driver.
+ * @brief Generic Serial Driver.
* @details This module implements a generic full duplex serial driver. The
- * driver implements a @p SerialDriver interface and uses I/O Queues for
- * communication between the upper and the lower driver. Event flags are used
- * to notify the application about incoming data, outgoing data and other I/O
- * events.<br>
- * The module also contains functions that make the implementation of the
- * interrupt service routines much easier.
+ * driver implements a @p SerialDriver interface and uses I/O Queues
+ * for communication between the upper and the lower driver. Event
+ * flags are used to notify the application about incoming data,
+ * outgoing data and other I/O events.<br>
+ * The module also contains functions that make the implementation
+ * of the interrupt service routines much easier.
* @pre In order to use the SERIAL driver the @p HAL_USE_SERIAL option
* must be enabled in @p halconf.h.
*
+ *
+ * @section serial_1 Driver State Machine
+ * The driver implements a state machine internally, not all the driver
+ * functionalities can be used in any moment, any transition not explicitly
+ * shown in the following diagram has to be considered an error and shall
+ * be captured by an assertion (if enabled).
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ uninit [label="SD_UNINIT", style="bold"];
+ stop [label="SD_STOP\nLow Power"];
+ ready [label="SD_READY\nClock Enabled"];
+
+ uninit -> stop [label=" sdInit()"];
+ stop -> stop [label="\nsdStop()"];
+ stop -> ready [label="\nsdStart()"];
+ ready -> stop [label="\nsdStop()"];
+ ready -> ready [label="\nsdStart()"];
+ ready -> ready [label="\nAny I/O operation"];
+ }
+ * @enddot
+ *
* @ingroup IO
*/
diff --git a/os/hal/dox/serial_usb.dox b/os/hal/dox/serial_usb.dox
new file mode 100644
index 000000000..c477b5288
--- /dev/null
+++ b/os/hal/dox/serial_usb.dox
@@ -0,0 +1,56 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/>.
+*/
+
+/**
+ * @defgroup SERIAL_USB Serial over USB Driver
+ * @brief Serial over USB Driver.
+ * @details This module implements an USB Communication Device Class
+ * (CDC) as a normal serial communication port accessible from
+ * the device application.
+ * @pre In order to use the USB over Serial driver the
+ * @p HAL_USE_SERIAL_USB option must be enabled in @p halconf.h.
+ *
+ * @section usb_serial_1 Driver State Machine
+ * The driver implements a state machine internally, not all the driver
+ * functionalities can be used in any moment, any transition not explicitly
+ * shown in the following diagram has to be considered an error and shall
+ * be captured by an assertion (if enabled).
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ uninit [label="SDU_UNINIT", style="bold"];
+ stop [label="SDU_STOP\nLow Power"];
+ ready [label="SDU_READY\nClock Enabled"];
+
+ uninit -> stop [label=" sduInit()"];
+ stop -> stop [label="\nsduStop()"];
+ stop -> ready [label="\nsduStart()"];
+ ready -> stop [label="\nsduStop()"];
+ ready -> ready [label="\nsduStart()"];
+ ready -> ready [label="\nAny I/O operation"];
+ }
+ * @enddot
+ *
+ * @ingroup IO
+ */
diff --git a/os/hal/dox/spi.dox b/os/hal/dox/spi.dox
index 7f68f3c40..047ff646e 100644
--- a/os/hal/dox/spi.dox
+++ b/os/hal/dox/spi.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,8 +20,10 @@
/**
* @defgroup SPI SPI Driver
- * @brief Generic SPI Driver.
- * @details This module implements a generic SPI driver.
+ * @brief Generic SPI Driver.
+ * @details This module implements a generic SPI (Serial Peripheral Interface)
+ * driver allowing bidirectional and monodirectional transfers,
+ * complex atomic transactions are supported as well.
* @pre In order to use the SPI driver the @p HAL_USE_SPI option
* must be enabled in @p halconf.h.
*
diff --git a/os/hal/dox/uart.dox b/os/hal/dox/uart.dox
index 192ce4d91..7fea38dcb 100644
--- a/os/hal/dox/uart.dox
+++ b/os/hal/dox/uart.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -19,26 +20,27 @@
/**
* @defgroup UART UART Driver
- * @brief Generic UART Driver.
- * @details This driver abstracts a generic UART peripheral, the API is
- * designed to be:
- * - Unbuffered and copy-less, transfers are always directly performed
- * from/to the application-level buffers without extra copy operations.
- * - Asynchronous, the API is always non blocking.
- * - Callbacks capable, operations completion and other events are notified
- * via callbacks.
- * .
- * Special hardware features like deep hardware buffers, DMA transfers
- * are hidden to the user but fully supportable by the low level
- * implementations.<br>
- * This driver model is best used where communication events are meant to
- * drive an higher level state machine, as example:
- * - RS485 drivers.
- * - Multipoint network drivers.
- * - Serial protocol decoders.
- * .
- * If your application requires a synchronoyus buffered driver then the
- * @ref SERIAL should be used instead.
+ * @brief Generic UART Driver.
+ * @details This driver abstracts a generic UART (Universal Asynchronous
+ * Receiver Transmitter) peripheral, the API is designed to be:
+ * - Unbuffered and copy-less, transfers are always directly performed
+ * from/to the application-level buffers without extra copy
+ * operations.
+ * - Asynchronous, the API is always non blocking.
+ * - Callbacks capable, operations completion and other events are
+ * notified using callbacks.
+ * .
+ * Special hardware features like deep hardware buffers, DMA transfers
+ * are hidden to the user but fully supportable by the low level
+ * implementations.<br>
+ * This driver model is best used where communication events are
+ * meant to drive an higher level state machine, as example:
+ * - RS485 drivers.
+ * - Multipoint network drivers.
+ * - Serial protocol decoders.
+ * .
+ * If your application requires a synchronoyus 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/dox/usb.dox b/os/hal/dox/usb.dox
new file mode 100644
index 000000000..62b3aaf12
--- /dev/null
+++ b/os/hal/dox/usb.dox
@@ -0,0 +1,239 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/>.
+*/
+
+/**
+ * @defgroup USB USB Driver
+ * @brief Generic USB Driver.
+ * @details This module implements a generic USB (Universal Serial Bus) driver
+ * supporting device-mode operations.
+ * @pre In order to use the USB driver the @p HAL_USE_USB option
+ * must be enabled in @p halconf.h.
+ *
+ * @section usb_1 Driver State Machine
+ * The driver implements a state machine internally, not all the driver
+ * functionalities can be used in any moment, any transition not explicitly
+ * shown in the following diagram has to be considered an error and shall
+ * be captured by an assertion (if enabled).
+ * @if LATEX_PDF
+ * @dot
+ digraph example {
+ size="5, 7";
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ stop [label="USB_STOP\nLow Power"];
+ uninit [label="USB_UNINIT", style="bold"];
+ ready [label="USB_READY\nClock Enabled"];
+ selected [label="\nUSB_SELECTED\naddress\nassigned"];
+ configured [label="\nUSB_ACTIVE\nconfiguration\nselected"];
+
+ uninit -> stop [label=" usbInit()", constraint=false];
+ stop -> stop [label="\nusbStop()"];
+ stop -> ready [label="\nusbStart()"];
+ ready -> stop [label="\nusbStop()"];
+ ready -> ready [label="\n\nusbStart()"];
+ ready -> ready [label="\nSUSPEND/WAKEUP\n>event_cb<"];
+ ready -> selected [label="\nSET_ADDRESS\n>event_cb<"];
+ selected -> ready [label="\nUSB RESET\n>event_cb<"];
+ selected -> selected [label="\nSUSPEND/WAKEUP\n>event_cb<\n\nValid EP0 Message\n>requests_hook_cb<\n\nGET DESCRIPTOR\n>get_descriptor_cb<"];
+ selected -> configured [label="\nSET_CONF(n)\n>event_cb<"];
+ configured -> selected [label="\nSET_CONF(0)\n>event_cb<"];
+ configured -> configured [label="\nSUSPEND/WAKEUP\n>event_cb<\n\nValid EP0 Message\n>requests_hook_cb<\n\nGET DESCRIPTOR\n>get_descriptor_cb<\n\nEndpoints Activity\n >in_cb< or >out_cb<"];
+ configured -> ready [label="\nUSB RESET\n>event_cb<"];
+ }
+ * @enddot
+ * @else
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ stop [label="USB_STOP\nLow Power"];
+ uninit [label="USB_UNINIT", style="bold"];
+ ready [label="USB_READY\nClock Enabled"];
+ selected [label="\nUSB_SELECTED\naddress\nassigned"];
+ configured [label="\nUSB_ACTIVE\nconfiguration\nselected"];
+
+ uninit -> stop [label=" usbInit()", constraint=false];
+ stop -> stop [label="\nusbStop()"];
+ stop -> ready [label="\nusbStart()"];
+ ready -> stop [label="\nusbStop()"];
+ ready -> ready [label="\n\nusbStart()"];
+ ready -> ready [label="\nSUSPEND/WAKEUP\n>event_cb<"];
+ ready -> selected [label="\nSET_ADDRESS\n>event_cb<"];
+ selected -> ready [label="\nUSB RESET\n>event_cb<"];
+ selected -> selected [label="\nSUSPEND/WAKEUP\n>event_cb<\n\nValid EP0 Message\n>requests_hook_cb<\n\nGET DESCRIPTOR\n>get_descriptor_cb<"];
+ selected -> configured [label="\nSET_CONF(n)\n>event_cb<"];
+ configured -> selected [label="\nSET_CONF(0)\n>event_cb<"];
+ configured -> configured [label="\nSUSPEND/WAKEUP\n>event_cb<\n\nValid EP0 Message\n>requests_hook_cb<\n\nGET DESCRIPTOR\n>get_descriptor_cb<\n\nEndpoints Activity\n >in_cb< or >out_cb<"];
+ configured -> ready [label="\nUSB RESET\n>event_cb<"];
+ }
+ * @enddot
+ * @endif
+ *
+ * @section usb_2 USB Operations
+ * The USB driver is quite complex and USB is complex in itself, it is
+ * recommended to study the USB specification before trying to use the
+ * driver.
+ *
+ * @subsection usb_2_1 USB Implementation
+ * The USB driver abstracts the inner details of the underlying USB hardware.
+ * The driver works asynchronously and communicates with the application
+ * using callbacks. The application is responsible of the descriptors and
+ * strings required by the USB device class to be implemented and of the
+ * handling of the specific messages sent over the endpoint zero. Standard
+ * messages are handled internally to the driver. The application can use
+ * hooks in order to handle custom messages or override the handling of the
+ * default handling of standard messages.
+ *
+ * @subsection usb_2_2 USB Endpoints
+ * USB endpoints are the objects that the application uses to exchange
+ * data with the host. There are two kind of endpoints:
+ * - <b>IN</b> endpoints are used by the application to transmit data to
+ * the host.<br>
+ * - <b>OUT</b> endpoints are used by the application to receive data from
+ * the host.
+ * .
+ * In ChibiOS/RT the endpoints can be configured in two distinct ways:
+ * - <b>Packet Mode</b>. In this mode the driver invokes a callback each
+ * time a packet has been received or transmitted. This mode is especially
+ * suited for those applications handling continuous streams of data.
+ * <br><br>
+ * States diagram for OUT endpoints in packet mode:
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ disabled [label="EP_DISABLED\nDisabled", style="bold"];
+ receiving [label="EP_BUSY\nReceiving Packet"];
+ idle [label="EP_IDLE\nPacket in Buffer"];
+
+ disabled -> receiving [label="\usbInitEndpointI()"];
+ receiving -> idle [label="\npacket received\n>out_cb<"];
+ idle -> receiving [label="\nusbReadPacketI()"];
+ receiving -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ idle -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ }
+ * @enddot
+ * <br><br>
+ * States diagram for IN endpoints in packet mode:
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ disabled [label="EP_DISABLED\nDisabled", style="bold"];
+ transmitting [label="EP_BUSY\nSending Packet"];
+ idle [label="EP_IDLE\nBuffer Empty"];
+
+ disabled -> idle [label="\usbInitEndpointI()"];
+ idle -> transmitting [label="\nusbWritePacketI()"];
+ transmitting -> idle [label="\npacket sent\n>in_cb<"];
+ transmitting -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ idle -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ }
+ * @enddot
+ * <br><br>
+ * - <b>Transaction Mode</b>. In this mode the driver invokes a callback
+ * only after a large, potentially multi-packet, transfer has been
+ * completed, a callback is invoked only at the end of the transfer.
+ * <br><br>
+ * States diagram for OUT endpoints in transaction mode:
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ disabled [label="EP_DISABLED\nDisabled", style="bold"];
+ receiving [label="EP_BUSY\nReceiving"];
+ idle [label="EP_IDLE\nReady"];
+
+ disabled -> idle [label="\usbInitEndpointI()"];
+ idle -> receiving [label="\usbStartReceiveI()"];
+ receiving -> receiving [label="\nmore packets"];
+ receiving -> idle [label="\nreception end\n>out_cb<"];
+ receiving -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ idle -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ }
+ * @enddot
+ * <br><br>
+ * States diagram for IN endpoints in transaction mode:
+ * @dot
+ digraph example {
+ rankdir="LR";
+ node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
+ width="0.9", height="0.9"];
+ edge [fontname=Helvetica, fontsize=8];
+
+ disabled [label="EP_DISABLED\nDisabled", style="bold"];
+ transmitting [label="EP_BUSY\nTransmitting"];
+ idle [label="EP_IDLE\nReady"];
+
+ disabled -> idle [label="\usbInitEndpointI()"];
+ idle -> transmitting [label="\nusbStartTransmitI()"];
+ transmitting -> transmitting [label="\nmore packets"];
+ transmitting -> idle [label="\ntransmission end\n>in_cb<"];
+ transmitting -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ idle -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
+ }
+ * @enddot
+ * <br><br>
+ * .
+ * @subsection usb_2_3 USB Packet Buffers
+ * An important difference between packet and transaction modes is that there
+ * is a dedicated endpoint buffer in packet mode while in transaction mode
+ * the application has to specify its own buffer for duration of the whole
+ * transfer.<br>
+ * Packet buffers cannot be accessed directly by the application because those
+ * could not be necessarily memory mapped, a buffer could be a FIFO or some
+ * other kind of memory accessible in a special way depending on the
+ * underlying hardware architecture, the functions @p usbReadPacketI() and
+ * @p usbWritePacketI() allow to access packet buffers in an abstract way.
+ *
+ * @subsection usb_2_4 USB Callbacks
+ * The USB driver uses callbacks in order to interact with the application.
+ * There are several kinds of callbacks to be handled:
+ * - Driver events callback. As example errors, suspend event, reset event
+ * etc.
+ * - Messages Hook callback. This hook allows the application to implement
+ * handling of custom messages or to override the default handling of
+ * standard messages on endpoint zero.
+ * - Descriptor Requested callback. When the driver endpoint zero handler
+ * receives a GET DESCRIPTOR message and needs to send a descriptor to
+ * the host it queries the application using this callback.
+ * - Start of Frame callback. This callback is invoked each time a SOF
+ * packet is received.
+ * - Endpoint callbacks. Each endpoint informs the application about I/O
+ * conditions using those callbacks.
+ * .
+ *
+ * @ingroup IO
+ */
diff --git a/os/hal/hal.dox b/os/hal/hal.dox
index 65c320d31..6ed44eacc 100644
--- a/os/hal/hal.dox
+++ b/os/hal/hal.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -50,14 +51,17 @@
* @subsection hal_device_driver_diagram Diagram
* @dot
digraph example {
+ graph [size="5, 7", pad="1.5, 0"];
node [shape=rectangle, fontname=Helvetica, fontsize=8,
fixedsize="true", width="2.0", height="0.4"];
edge [fontname=Helvetica, fontsize=8];
+
app [label="Application"];
hld [label="High Level Driver"];
lld [label="Low Level Driver"];
hw [label="Microcontroller Hardware"];
hal_lld [label="HAL shared low level code"];
+
app->hld;
hld->lld;
lld-> hw;
diff --git a/os/hal/hal.mk b/os/hal/hal.mk
index 233ac66d1..762bda57f 100644
--- a/os/hal/hal.mk
+++ b/os/hal/hal.mk
@@ -3,10 +3,13 @@
HALSRC = ${CHIBIOS}/os/hal/src/hal.c \
${CHIBIOS}/os/hal/src/adc.c \
${CHIBIOS}/os/hal/src/can.c \
+ ${CHIBIOS}/os/hal/src/gpt.c \
${CHIBIOS}/os/hal/src/i2c.c \
+ ${CHIBIOS}/os/hal/src/icu.c \
${CHIBIOS}/os/hal/src/mac.c \
${CHIBIOS}/os/hal/src/pal.c \
${CHIBIOS}/os/hal/src/pwm.c \
+ ${CHIBIOS}/os/hal/src/sdc.c \
${CHIBIOS}/os/hal/src/serial.c \
${CHIBIOS}/os/hal/src/spi.c \
${CHIBIOS}/os/hal/src/uart.c \
diff --git a/os/hal/include/adc.h b/os/hal/include/adc.h
index d94d99aa3..a236a040a 100644
--- a/os/hal/include/adc.h
+++ b/os/hal/include/adc.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -92,9 +93,9 @@ typedef enum {
* @notapi
*/
#define _adc_reset_i(adcp) { \
- if ((adcp)->ad_thread != NULL) { \
- Thread *tp = (adcp)->ad_thread; \
- (adcp)->ad_thread = NULL; \
+ if ((adcp)->thread != NULL) { \
+ Thread *tp = (adcp)->thread; \
+ (adcp)->thread = NULL; \
tp->p_u.rdymsg = RDY_RESET; \
chSchReadyI(tp); \
} \
@@ -108,9 +109,9 @@ typedef enum {
* @notapi
*/
#define _adc_reset_s(adcp) { \
- if ((adcp)->ad_thread != NULL) { \
- Thread *tp = (adcp)->ad_thread; \
- (adcp)->ad_thread = NULL; \
+ if ((adcp)->thread != NULL) { \
+ Thread *tp = (adcp)->thread; \
+ (adcp)->thread = NULL; \
chSchWakeupS(tp, RDY_RESET); \
} \
}
@@ -123,10 +124,11 @@ typedef enum {
* @notapi
*/
#define _adc_wakeup_isr(adcp) { \
- if ((adcp)->ad_thread != NULL) { \
- Thread *tp = (adcp)->ad_thread; \
- (adcp)->ad_thread = NULL; \
+ if ((adcp)->thread != NULL) { \
+ Thread *tp; \
chSysLockFromIsr(); \
+ tp = (adcp)->thread; \
+ (adcp)->thread = NULL; \
tp->p_u.rdymsg = RDY_OK; \
chSchReadyI(tp); \
chSysUnlockFromIsr(); \
@@ -152,9 +154,8 @@ typedef enum {
* @notapi
*/
#define _adc_isr_half_code(adcp) { \
- if ((adcp)->ad_grpp->acg_endcb != NULL) { \
- (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples, \
- (adcp)->ad_depth / 2); \
+ if ((adcp)->grpp->end_cb != NULL) { \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth / 2); \
} \
}
@@ -173,40 +174,40 @@ typedef enum {
* @notapi
*/
#define _adc_isr_full_code(adcp) { \
- if ((adcp)->ad_grpp->acg_circular) { \
+ if ((adcp)->grpp->circular) { \
/* Callback handling.*/ \
- if ((adcp)->ad_grpp->acg_endcb != NULL) { \
- if ((adcp)->ad_depth > 1) { \
+ if ((adcp)->grpp->end_cb != NULL) { \
+ if ((adcp)->depth > 1) { \
/* Invokes the callback passing the 2nd half of the buffer.*/ \
- size_t half = (adcp)->ad_depth / 2; \
- (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples + half, half); \
+ size_t half = (adcp)->depth / 2; \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples + half, half); \
} \
else { \
/* Invokes the callback passing the whole buffer.*/ \
- (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples, \
- (adcp)->ad_depth); \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth); \
} \
} \
} \
else { \
/* End conversion.*/ \
adc_lld_stop_conversion(adcp); \
- if ((adcp)->ad_grpp->acg_endcb != NULL) { \
- (adcp)->ad_state = ADC_COMPLETE; \
- if ((adcp)->ad_depth > 1) { \
+ if ((adcp)->grpp->end_cb != NULL) { \
+ (adcp)->state = ADC_COMPLETE; \
+ if ((adcp)->depth > 1) { \
/* Invokes the callback passing the 2nd half of the buffer.*/ \
- size_t half = (adcp)->ad_depth / 2; \
- (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples + half, half); \
+ size_t half = (adcp)->depth / 2; \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples + half, half); \
} \
else { \
/* Invokes the callback passing the whole buffer.*/ \
- (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples, \
- (adcp)->ad_depth); \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth); \
} \
- if ((adcp)->ad_state == ADC_COMPLETE) \
- (adcp)->ad_state = ADC_READY; \
+ if ((adcp)->state == ADC_COMPLETE) \
+ (adcp)->state = ADC_READY; \
} \
- (adcp)->ad_grpp = NULL; \
+ else \
+ (adcp)->state = ADC_READY; \
+ (adcp)->grpp = NULL; \
_adc_wakeup_isr(adcp); \
} \
}
diff --git a/os/hal/include/can.h b/os/hal/include/can.h
index dc258193a..538284b3b 100644
--- a/os/hal/include/can.h
+++ b/os/hal/include/can.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -103,7 +104,7 @@ typedef enum {
*
* @iclass
*/
-#define canAddFlagsI(canp, mask) ((canp)->cd_status |= (mask))
+#define canAddFlagsI(canp, mask) ((canp)->status |= (mask))
/*===========================================================================*/
/* External declarations. */
diff --git a/os/hal/include/gpt.h b/os/hal/include/gpt.h
new file mode 100644
index 000000000..5bb385078
--- /dev/null
+++ b/os/hal/include/gpt.h
@@ -0,0 +1,105 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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 gpt.h
+ * @brief GPT Driver macros and structures.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#ifndef _GPT_H_
+#define _GPT_H_
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ GPT_UNINIT = 0, /**< Not initialized. */
+ GPT_STOP = 1, /**< Stopped. */
+ GPT_READY = 2, /**< Ready. */
+ GPT_CONTINUOUS = 3, /**< Active in continuous mode. */
+ GPT_ONESHOT = 4 /**< Active in one shot mode. */
+} gptstate_t;
+
+/**
+ * @brief Type of a structure representing a GPT driver.
+ */
+typedef struct GPTDriver GPTDriver;
+
+/**
+ * @brief GPT notification callback type.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ */
+typedef void (*gptcallback_t)(GPTDriver *gptp);
+
+#include "gpt_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void gptInit(void);
+ void gptObjectInit(GPTDriver *gptp);
+ void gptStart(GPTDriver *gptp, const GPTConfig *config);
+ void gptStop(GPTDriver *gptp);
+ void gptStartContinuous(GPTDriver *gptp, gptcnt_t interval);
+ void gptStartContinuousI(GPTDriver *gptp, gptcnt_t interval);
+ void gptStartOneShot(GPTDriver *gptp, gptcnt_t interval);
+ void gptStartOneShotI(GPTDriver *gptp, gptcnt_t interval);
+ void gptStopTimer(GPTDriver *gptp);
+ void gptStopTimerI(GPTDriver *gptp);
+ void gptPolledDelay(GPTDriver *gptp, gptcnt_t interval);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_GPT */
+
+#endif /* _GPT_H_ */
+
+/** @} */
diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h
index 822dafc35..1ed893aab 100644
--- a/os/hal/include/hal.h
+++ b/os/hal/include/hal.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -36,10 +37,13 @@
#include "pal.h"
#include "adc.h"
#include "can.h"
+#include "gpt.h"
#include "i2c.h"
+#include "icu.h"
#include "mac.h"
#include "pwm.h"
#include "serial.h"
+#include "sdc.h"
#include "spi.h"
#include "uart.h"
#include "usb.h"
diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h
index 1c9238859..f5465985b 100644
--- a/os/hal/include/i2c.h
+++ b/os/hal/include/i2c.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/include/icu.h b/os/hal/include/icu.h
new file mode 100644
index 000000000..38fed2788
--- /dev/null
+++ b/os/hal/include/icu.h
@@ -0,0 +1,169 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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 icu.h
+ * @brief ICU Driver macros and structures.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#ifndef _ICU_H_
+#define _ICU_H_
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ ICU_UNINIT = 0, /**< Not initialized. */
+ ICU_STOP = 1, /**< Stopped. */
+ ICU_READY = 2, /**< Ready. */
+ ICU_WAITING = 3, /**< Waiting first edge. */
+ ICU_ACTIVE = 4, /**< Active cycle phase. */
+ ICU_IDLE = 5, /**< Idle cycle phase. */
+} icustate_t;
+
+/**
+ * @brief Type of a structure representing an ICU driver.
+ */
+typedef struct ICUDriver ICUDriver;
+
+/**
+ * @brief ICU notification callback type.
+ *
+ * @param[in] icup pointer to a @p ICUDriver object
+ */
+typedef void (*icucallback_t)(ICUDriver *icup);
+
+#include "icu_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @iclass
+ */
+#define icuEnableI(icup) icu_lld_enable(icup)
+
+/**
+ * @brief Disables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @iclass
+ */
+#define icuDisableI(icup) icu_lld_disable(icup)
+
+/**
+ * @brief Returns the width of the latest pulse.
+ * @details The pulse width is defined as number of ticks between the start
+ * edge and the stop edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @iclass
+ */
+#define icuGetWidthI(icup) icu_lld_get_width(icup)
+
+/**
+ * @brief Returns the width of the latest cycle.
+ * @details The cycle width is defined as number of ticks between a start
+ * edge and the next start edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @iclass
+ */
+#define icuGetPeriodI(icup) icu_lld_get_period(icup)
+
+/**
+ * @brief Common ISR code, ICU width event.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+#define _icu_isr_invoke_width_cb(icup) { \
+ (icup)->state = ICU_IDLE; \
+ (icup)->config->width_cb(icup); \
+}
+
+/**
+ * @brief Common ISR code, ICU period event.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+#define _icu_isr_invoke_period_cb(icup) { \
+ icustate_t previous_state = (icup)->state; \
+ (icup)->state = ICU_ACTIVE; \
+ if (previous_state != ICU_WAITING) \
+ (icup)->config->period_cb(icup); \
+}
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void icuInit(void);
+ void icuObjectInit(ICUDriver *icup);
+ void icuStart(ICUDriver *icup, const ICUConfig *config);
+ void icuStop(ICUDriver *icup);
+ void icuEnable(ICUDriver *icup);
+ void icuDisable(ICUDriver *icup);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ICU */
+
+#endif /* _ICU_H_ */
+
+/** @} */
diff --git a/os/hal/include/mac.h b/os/hal/include/mac.h
index 8978f007e..ad3c7b4dc 100644
--- a/os/hal/include/mac.h
+++ b/os/hal/include/mac.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -64,7 +65,7 @@
* @api
*/
#if CH_USE_EVENTS || defined(__DOXYGEN__)
-#define macGetReceiveEventSource(macp) (&(macp)->md_rdevent)
+#define macGetReceiveEventSource(macp) (&(macp)->rdevent)
#endif
/**
diff --git a/os/hal/include/mii.h b/os/hal/include/mii.h
index 87612273a..7199ee86d 100644
--- a/os/hal/include/mii.h
+++ b/os/hal/include/mii.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -18,7 +19,8 @@
*/
/*
- * Parts of this file are borrowed by the Linux include file linux/mii.h:
+ * Parts of this file have been borrowed from the Linux include file
+ * linux/mii.h:
* Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
*/
@@ -185,4 +187,4 @@
#endif /* _MII_H_ */
-/*-* @} */
+/** @} */
diff --git a/os/hal/include/mmc_spi.h b/os/hal/include/mmc_spi.h
index 241fae54a..6940ca479 100644
--- a/os/hal/include/mmc_spi.h
+++ b/os/hal/include/mmc_spi.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -18,7 +19,7 @@
*/
/**
- * @file mmc_spi.h
+ * @file spi.h
* @brief MMC over SPI driver header.
*
* @addtogroup MMC_SPI
@@ -133,47 +134,47 @@ typedef struct {
/**
* @brief Driver state.
*/
- mmcstate_t mmc_state;
+ mmcstate_t state;
/**
* @brief Current configuration data.
*/
- const MMCConfig *mmc_config;
+ const MMCConfig *config;
/**
* @brief SPI driver associated to this MMC driver.
*/
- SPIDriver *mmc_spip;
+ SPIDriver *spip;
/**
* @brief SPI low speed configuration used during initialization.
*/
- const SPIConfig *mmc_lscfg;
+ const SPIConfig *lscfg;
/**
* @brief SPI high speed configuration used during transfers.
*/
- const SPIConfig *mmc_hscfg;
+ const SPIConfig *hscfg;
/**
* @brief Write protect status query function.
*/
- mmcquery_t mmc_is_protected;
+ mmcquery_t is_protected;
/**
* @brief Insertion status query function.
*/
- mmcquery_t mmc_is_inserted;
+ mmcquery_t is_inserted;
/**
* @brief Card insertion event source.
*/
- EventSource mmc_inserted_event;
+ EventSource inserted_event;
/**
* @brief Card removal event source.
*/
- EventSource mmc_removed_event;
+ EventSource removed_event;
/**
* @brief MMC insertion polling timer.
*/
- VirtualTimer mmc_vt;
+ VirtualTimer vt;
/**
* @brief Insertion counter.
*/
- uint_fast8_t mmc_cnt;
+ uint_fast8_t cnt;
} MMCDriver;
/*===========================================================================*/
@@ -188,7 +189,7 @@ typedef struct {
*
* @api
*/
-#define mmcGetDriverState(mmcp) ((mmcp)->mmc_state)
+#define mmcGetDriverState(mmcp) ((mmcp)->state)
/**
* @brief Returns the write protect status.
@@ -200,7 +201,7 @@ typedef struct {
*
* @api
*/
-#define mmcIsWriteProtected(mmcp) ((mmcp)->mmc_is_protected())
+#define mmcIsWriteProtected(mmcp) ((mmcp)->is_protected())
/*===========================================================================*/
/* External declarations. */
diff --git a/os/hal/include/pal.h b/os/hal/include/pal.h
index 6f3c4a7e5..e9d0e31d8 100644
--- a/os/hal/include/pal.h
+++ b/os/hal/include/pal.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -123,17 +124,17 @@ typedef struct {
/**
* @brief Port identifier.
*/
- ioportid_t bus_portid;
+ ioportid_t portid;
/**
* @brief Bus mask aligned to port bit 0.
* @note The bus mask implicitly define the bus width. A logical AND is
* performed on the bus data.
*/
- ioportmask_t bus_mask;
+ ioportmask_t mask;
/**
* @brief Offset, within the port, of the least significant bit of the bus.
*/
- uint_fast8_t bus_offset;
+ uint_fast8_t offset;
} IOBus;
/*===========================================================================*/
@@ -262,9 +263,8 @@ typedef struct {
* @api
*/
#if !defined(pal_lld_setport) || defined(__DOXYGEN__)
-#define palSetPort(port, bits) { \
- palWritePort(port, palReadLatch(port) | (bits)); \
-}
+#define palSetPort(port, bits) \
+ palWritePort(port, palReadLatch(port) | (bits))
#else
#define palSetPort(port, bits) pal_lld_setport(port, bits)
#endif
@@ -285,9 +285,8 @@ typedef struct {
* @api
*/
#if !defined(pal_lld_clearport) || defined(__DOXYGEN__)
-#define palClearPort(port, bits) { \
- palWritePort(port, palReadLatch(port) & ~(bits)); \
-}
+#define palClearPort(port, bits) \
+ palWritePort(port, palReadLatch(port) & ~(bits))
#else
#define palClearPort(port, bits) pal_lld_clearport(port, bits)
#endif
@@ -308,9 +307,8 @@ typedef struct {
* @api
*/
#if !defined(pal_lld_toggleport) || defined(__DOXYGEN__)
-#define palTogglePort(port, bits) { \
- palWritePort(port, palReadLatch(port) ^ (bits)); \
-}
+#define palTogglePort(port, bits) \
+ palWritePort(port, palReadLatch(port) ^ (bits))
#else
#define palTogglePort(port, bits) pal_lld_toggleport(port, bits)
#endif
@@ -346,10 +344,9 @@ typedef struct {
* @api
*/
#if !defined(pal_lld_writegroup) || defined(__DOXYGEN__)
-#define palWriteGroup(port, mask, offset, bits) { \
+#define palWriteGroup(port, mask, offset, bits) \
palWritePort(port, (palReadLatch(port) & ~((mask) << (offset))) | \
- (((bits) & (mask)) << (offset))); \
-}
+ (((bits) & (mask)) << (offset)))
#else
#define palWriteGroup(port, mask, offset, bits) \
pal_lld_writegroup(port, mask, offset, bits)
@@ -415,10 +412,9 @@ typedef struct {
* @api
*/
#if !defined(pal_lld_writepad) || defined(__DOXYGEN__)
-#define palWritePad(port, pad, bit) { \
+#define palWritePad(port, pad, bit) \
palWritePort(port, (palReadLatch(port) & ~PAL_PORT_BIT(pad)) | \
- (((bit) & 1) << pad)); \
-}
+ (((bit) & 1) << pad))
#else
#define palWritePad(port, pad, bit) pal_lld_writepad(port, pad, bit)
#endif
diff --git a/os/hal/include/pwm.h b/os/hal/include/pwm.h
index 6570e9fdf..2ffd3599c 100644
--- a/os/hal/include/pwm.h
+++ b/os/hal/include/pwm.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -34,6 +35,26 @@
/* Driver constants. */
/*===========================================================================*/
+/**
+ * @brief Standard output modes mask.
+ */
+#define PWM_OUTPUT_MASK 0x0F
+
+/**
+ * @brief Output not driven, callback only.
+ */
+#define PWM_OUTPUT_DISABLED 0x00
+
+/**
+ * @brief Positive PWM logic, active is logic level one.
+ */
+#define PWM_OUTPUT_ACTIVE_HIGH 0x01
+
+/**
+ * @brief Inverse PWM logic, active is logic level zero.
+ */
+#define PWM_OUTPUT_ACTIVE_LOW 0x02
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -56,13 +77,16 @@ typedef enum {
} pwmstate_t;
/**
- * @brief PWM logic mode.
+ * @brief Type of a structure representing a PWM driver.
*/
-typedef enum {
- PWM_OUTPUT_DISABLED = 0, /**< Output not driven, callback only. */
- PWM_OUTPUT_ACTIVE_HIGH = 1, /**< Idle is logic level 0. */
- PWM_OUTPUT_ACTIVE_LOW = 2 /**< Idle is logic level 1. */
-} pwmmode_t;
+typedef struct PWMDriver PWMDriver;
+
+/**
+ * @brief PWM notification callback type.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ */
+typedef void (*pwmcallback_t)(PWMDriver *pwmp);
#include "pwm_lld.h"
@@ -71,12 +95,85 @@ typedef enum {
/*===========================================================================*/
/**
+ * @brief Converts from fraction to pulse width.
+ * @note Be careful with rounding errors, this is integer math not magic.
+ * You can specify tenths of thousandth but make sure you have the
+ * proper hardware resolution by carefully choosing the clock source
+ * and prescaler settings, see @p PWM_COMPUTE_PSC.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] denominator denominator of the fraction
+ * @param[in] numerator numerator of the fraction
+ * @return The pulse width to be passed to @p pwmEnableChannel().
+ *
+ * @api
+ */
+#define PWM_FRACTION_TO_WIDTH(pwmp, denominator, numerator) \
+ ((uint16_t)((((uint32_t)(pwmp)->period) * \
+ (uint32_t)(numerator)) / (uint32_t)(denominator)))
+
+/**
+ * @brief Converts from degrees to pulse width.
+ * @note Be careful with rounding errors, this is integer math not magic.
+ * You can specify hundredths of degrees but make sure you have the
+ * proper hardware resolution by carefully choosing the clock source
+ * and prescaler settings, see @p PWM_COMPUTE_PSC.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] degrees degrees as an integer between 0 and 36000
+ * @return The pulse width to be passed to @p pwmEnableChannel().
+ *
+ * @api
+ */
+#define PWM_DEGREES_TO_WIDTH(pwmp, degrees) \
+ PWM_FRACTION_TO_WIDTH(pwmp, 36000, degrees)
+
+/**
+ * @brief Converts from percentage to pulse width.
+ * @note Be careful with rounding errors, this is integer math not magic.
+ * You can specify tenths of thousandth but make sure you have the
+ * proper hardware resolution by carefully choosing the clock source
+ * and prescaler settings, see @p PWM_COMPUTE_PSC.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] percentage percentage as an integer between 0 and 10000
+ * @return The pulse width to be passed to @p pwmEnableChannel().
+ *
+ * @api
+ */
+#define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \
+ PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage)
+
+/**
+ * @brief Changes the period the PWM peripheral.
+ * @details This function changes the period of a PWM unit that has already
+ * been activated using @p pwmStart().
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The PWM unit period is changed to the new value.
+ * @note If a period is specified that is shorter than the pulse width
+ * programmed in one of the channels then the behavior is not
+ * guaranteed.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] period new cycle time in ticks
+ *
+ * @iclass
+ */
+#define pwmChangePeriodI(pwmp, period) { \
+ (pwmp)->period = (period); \
+ pwm_lld_change_period(pwmp, period); \
+}
+
+/**
* @brief Enables a PWM channel.
- * @details Programs (or reprograms) a PWM channel.
- * @note This function has to be invoked from a lock zone.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is active using the specified configuration.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier
+ * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
* @param[in] width PWM pulse width as clock pulses number
*
* @iclass
@@ -85,13 +182,16 @@ typedef enum {
pwm_lld_enable_channel(pwmp, channel, width)
/**
- * @brief Disables a PWM channel.
- * @details The channel is disabled and its output line returned to the
+ * @brief Disables a PWM channel.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is disabled and its output line returned to the
* idle state.
- * @note This function has to be invoked from a lock zone.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier
+ * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
*
* @iclass
*/
@@ -109,6 +209,7 @@ extern "C" {
void pwmObjectInit(PWMDriver *pwmp);
void pwmStart(PWMDriver *pwmp, const PWMConfig *config);
void pwmStop(PWMDriver *pwmp);
+ void pwmChangePeriod(PWMDriver *pwmp, pwmcnt_t period);
void pwmEnableChannel(PWMDriver *pwmp,
pwmchannel_t channel,
pwmcnt_t width);
diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h
new file mode 100644
index 000000000..afc3a6aba
--- /dev/null
+++ b/os/hal/include/sdc.h
@@ -0,0 +1,234 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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 sdc.h
+ * @brief SDC Driver macros and structures.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#ifndef _SDC_H_
+#define _SDC_H_
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+#define SDC_BLOCK_SIZE 512 /**< Fixed block size. */
+
+/**
+ * @brief Fixed pattern for CMD8.
+ */
+#define SDC_CMD8_PATTERN 0x000001AA
+
+#define SDC_MODE_CARDTYPE_MASK 0xF /**< @brief Card type mask. */
+#define SDC_MODE_CARDTYPE_SDV11 0 /**< @brief Card is SD V1.1.*/
+#define SDC_MODE_CARDTYPE_SDV20 1 /**< @brief Card is SD V2.0.*/
+#define SDC_MODE_CARDTYPE_MMC 2 /**< @brief Card is MMC. */
+#define SDC_MODE_HIGH_CAPACITY 0x10 /**< @brief High cap.card. */
+
+/**
+ * @brief Mask of error bits in R1 responses.
+ */
+#define SDC_R1_ERROR_MASK 0xFDFFE008
+
+#define SDC_STS_IDLE 0
+#define SDC_STS_READY 1
+#define SDC_STS_IDENT 2
+#define SDC_STS_STBY 3
+#define SDC_STS_TRAN 4
+#define SDC_STS_DATA 5
+#define SDC_STS_RCV 6
+#define SDC_STS_PRG 7
+#define SDC_STS_DIS 8
+
+#define SDC_CMD_GO_IDLE_STATE 0
+#define SDC_CMD_INIT 1
+#define SDC_CMD_ALL_SEND_CID 2
+#define SDC_CMD_SEND_RELATIVE_ADDR 3
+#define SDC_CMD_SET_BUS_WIDTH 6
+#define SDC_CMD_SEL_DESEL_CARD 7
+#define SDC_CMD_SEND_IF_COND 8
+#define SDC_CMD_SEND_CSD 9
+#define SDC_CMD_STOP_TRANSMISSION 12
+#define SDC_CMD_SEND_STATUS 13
+#define SDC_CMD_SET_BLOCKLEN 16
+#define SDC_CMD_READ_SINGLE_BLOCK 17
+#define SDC_CMD_READ_MULTIPLE_BLOCK 18
+#define SDC_CMD_SET_BLOCK_COUNT 23
+#define SDC_CMD_WRITE_BLOCK 24
+#define SDC_CMD_WRITE_MULTIPLE_BLOCK 25
+#define SDC_CMD_APP_OP_COND 41
+#define SDC_CMD_LOCK_UNLOCK 42
+#define SDC_CMD_APP_CMD 55
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Number of initialization attempts before rejecting the card.
+ * @note Attempts are performed at 10mS intevals.
+ */
+#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
+#define SDC_INIT_RETRY 100
+#endif
+
+/**
+ * @brief Include support for MMC cards.
+ * @note MMC support is not yet implemented so this option must be kept
+ * at @p FALSE.
+ */
+#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
+#define SDC_MMC_SUPPORT FALSE
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ */
+#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
+#define SDC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ SDC_UNINIT = 0, /**< Not initialized. */
+ SDC_STOP = 1, /**< Stopped. */
+ SDC_READY = 2, /**< Ready. */
+ SDC_CONNECTING = 3, /**< Card connection in progress. */
+ SDC_DISCONNECTING = 4, /**< Card disconnection in progress. */
+ SDC_ACTIVE = 5, /**< Cart initialized. */
+ SDC_READING = 6, /**< Read operation in progress. */
+ SDC_WRITING = 7, /**< Write operation in progress. */
+} sdcstate_t;
+
+#include "sdc_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Evaluates to @p TRUE if the R1 response contains error flags.
+ *
+ * @param[in] r1 the r1 response
+ */
+#define SDC_R1_ERROR(r1) (((r1) & SDC_R1_ERROR_MASK) != 0)
+
+/**
+ * @brief Returns the status field of an R1 response.
+ *
+ * @param[in] r1 the r1 response
+ */
+#define SDC_R1_STS(r1) (((r1) >> 9) & 15)
+
+/**
+ * @brief Evaluates to @p TRUE if the R1 response indicates a locked card.
+ *
+ * @param[in] r1 the r1 response
+ */
+#define SDC_R1_IS_CARD_LOCKED(r1) (((r1) >> 21) & 1)
+
+/**
+ * @brief Returns the driver state.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The driver state.
+ *
+ * @api
+ */
+#define sdcGetDriverState(sdcp) ((sdcp)->state)
+
+/**
+ * @brief Returns the card insertion status.
+ * @note This macro wraps a low level function named
+ * @p sdc_lld_is_card_inserted(), this function must be
+ * provided by the application because it is not part of the
+ * SDC driver.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The card state.
+ * @retval FALSE card not inserted.
+ * @retval TRUE card inserted.
+ *
+ * @api
+ */
+#define sdcIsCardInserted(sdcp) (sdc_lld_is_card_inserted(sdcp))
+
+/**
+ * @brief Returns the write protect status.
+ * @note This macro wraps a low level function named
+ * @p sdc_lld_is_write_protected(), this function must be
+ * provided by the application because it is not part of the
+ * SDC driver.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The card state.
+ * @retval FALSE card not inserted.
+ * @retval TRUE card inserted.
+ *
+ * @api
+ */
+#define sdcIsWriteProtected(sdcp) (sdc_lld_is_write_protected(sdcp))
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void sdcInit(void);
+ void sdcObjectInit(SDCDriver *sdcp);
+ void sdcStart(SDCDriver *sdcp, const SDCConfig *config);
+ void sdcStop(SDCDriver *sdcp);
+ bool_t sdcConnect(SDCDriver *sdcp);
+ bool_t sdcDisconnect(SDCDriver *sdcp);
+ bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buffer, uint32_t n);
+ bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buffer, uint32_t n);
+ bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SDC */
+
+#endif /* _SDC_H_ */
+
+/** @} */
diff --git a/os/hal/include/serial.h b/os/hal/include/serial.h
index 57240e78b..a8c3c1aca 100644
--- a/os/hal/include/serial.h
+++ b/os/hal/include/serial.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/include/serial_usb.h b/os/hal/include/serial_usb.h
index b75f6fe59..8e518238d 100644
--- a/os/hal/include/serial_usb.h
+++ b/os/hal/include/serial_usb.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -53,8 +54,9 @@
/* Derived constants and error checks. */
/*===========================================================================*/
-#if !HAL_USE_USB && !CH_USE_EVENTS
-#error "Serial over USB Driver requires HAL_USE_USB and CH_USE_EVENTS"
+#if !HAL_USE_USB && !CH_USE_QUEUES && !CH_USE_EVENTS
+#error "Serial over USB Driver requires HAL_USE_USB, CH_USE_QUEUES, "
+ "CH_USE_EVENTS"
#endif
/*===========================================================================*/
@@ -84,23 +86,11 @@ typedef struct {
/**
* @brief USB driver to use.
*/
- USBDriver *usbp;
+ USBDriver *usbp;
/**
* @brief USB driver configuration structure.
*/
- USBConfig usb_config;
- /*
- * @brief Endpoint used for data transmission.
- */
- usbep_t data_request_ep;
- /*
- * @brief Endpoint used for data reception.
- */
- usbep_t data_available_ep;
- /*
- * @brief Endpoint used for interrupt request.
- */
- usbep_t interrupt_request_ep;
+ USBConfig usb_config;
} SerialUSBConfig;
/**
@@ -114,9 +104,9 @@ typedef struct {
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
- /* Input circular buffer.*/ \
+ /* Input buffer.*/ \
uint8_t ib[SERIAL_USB_BUFFERS_SIZE]; \
- /* Output circular buffer.*/ \
+ /* Output buffer.*/ \
uint8_t ob[SERIAL_USB_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/ \
/* Current configuration data.*/ \
@@ -164,9 +154,9 @@ extern "C" {
void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config);
void sduStop(SerialUSBDriver *sdup);
bool_t sduRequestsHook(USBDriver *usbp);
- void sduDataRequest(USBDriver *usbp, usbep_t ep);
- void sduDataAvailable(USBDriver *usbp, usbep_t ep);
- void sduInterruptRequest(USBDriver *usbp, usbep_t ep);
+ void sduDataTransmitted(USBDriver *usbp, usbep_t ep);
+ void sduDataReceived(USBDriver *usbp, usbep_t ep);
+ void sduInterruptTransmitted(USBDriver *usbp, usbep_t ep);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/include/spi.h b/os/hal/include/spi.h
index ccf3e4e63..104dd9d3e 100644
--- a/os/hal/include/spi.h
+++ b/os/hal/include/spi.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -120,7 +121,7 @@ typedef enum {
* @iclass
*/
#define spiStartIgnoreI(spip, n) { \
- (spip)->spd_state = SPI_ACTIVE; \
+ (spip)->state = SPI_ACTIVE; \
spi_lld_ignore(spip, n); \
}
@@ -142,7 +143,7 @@ typedef enum {
* @iclass
*/
#define spiStartExchangeI(spip, n, txbuf, rxbuf) { \
- (spip)->spd_state = SPI_ACTIVE; \
+ (spip)->state = SPI_ACTIVE; \
spi_lld_exchange(spip, n, txbuf, rxbuf); \
}
@@ -162,7 +163,7 @@ typedef enum {
* @iclass
*/
#define spiStartSendI(spip, n, txbuf) { \
- (spip)->spd_state = SPI_ACTIVE; \
+ (spip)->state = SPI_ACTIVE; \
spi_lld_send(spip, n, txbuf); \
}
@@ -182,7 +183,7 @@ typedef enum {
* @iclass
*/
#define spiStartReceiveI(spip, n, rxbuf) { \
- (spip)->spd_state = SPI_ACTIVE; \
+ (spip)->state = SPI_ACTIVE; \
spi_lld_receive(spip, n, rxbuf); \
}
@@ -215,9 +216,9 @@ typedef enum {
* @notapi
*/
#define _spi_wait_s(spip) { \
- chDbgAssert((spip)->spd_thread == NULL, \
+ chDbgAssert((spip)->thread == NULL, \
"_spi_wait(), #1", "already waiting"); \
- (spip)->spd_thread = chThdSelf(); \
+ (spip)->thread = chThdSelf(); \
chSchGoSleepS(THD_STATE_SUSPENDED); \
}
@@ -229,9 +230,9 @@ typedef enum {
* @notapi
*/
#define _spi_wakeup_isr(spip) { \
- if ((spip)->spd_thread != NULL) { \
- Thread *tp = (spip)->spd_thread; \
- (spip)->spd_thread = NULL; \
+ if ((spip)->thread != NULL) { \
+ Thread *tp = (spip)->thread; \
+ (spip)->thread = NULL; \
chSysLockFromIsr(); \
chSchReadyI(tp); \
chSysUnlockFromIsr(); \
@@ -257,12 +258,14 @@ typedef enum {
* @notapi
*/
#define _spi_isr_code(spip) { \
- if ((spip)->spd_config->spc_endcb) { \
- (spip)->spd_state = SPI_COMPLETE; \
- (spip)->spd_config->spc_endcb(spip); \
- if ((spip)->spd_state == SPI_COMPLETE) \
- (spip)->spd_state = SPI_READY; \
+ if ((spip)->config->end_cb) { \
+ (spip)->state = SPI_COMPLETE; \
+ (spip)->config->end_cb(spip); \
+ if ((spip)->state == SPI_COMPLETE) \
+ (spip)->state = SPI_READY; \
} \
+ else \
+ (spip)->state = SPI_READY; \
_spi_wakeup_isr(spip); \
}
diff --git a/os/hal/include/uart.h b/os/hal/include/uart.h
index 2ea69309f..148aa6877 100644
--- a/os/hal/include/uart.h
+++ b/os/hal/include/uart.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/include/usb.h b/os/hal/include/usb.h
index 9f0d95837..c4cf68fe2 100644
--- a/os/hal/include/usb.h
+++ b/os/hal/include/usb.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -73,6 +74,112 @@
#define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1
#define USB_FEATURE_TEST_MODE 2
+#define USB_EARLY_SET_ADDRESS 0
+#define USB_LATE_SET_ADDRESS 1
+
+/**
+ * @brief Helper macro for index values into descriptor strings.
+ */
+#define USB_DESC_INDEX(i) ((uint8_t)(i))
+
+/**
+ * @brief Helper macro for byte values into descriptor strings.
+ */
+#define USB_DESC_BYTE(b) ((uint8_t)(b))
+
+/**
+ * @brief Helper macro for word values into descriptor strings.
+ */
+#define USB_DESC_WORD(w) \
+ (uint8_t)((w) & 255), \
+ (uint8_t)(((w) >> 8) & 255)
+
+/**
+ * @brief Helper macro for BCD values into descriptor strings.
+ */
+#define USB_DESC_BCD(bcd) \
+ (uint8_t)((bcd) & 255), \
+ (uint8_t)(((bcd) >> 8) & 255)
+
+/**
+ * @brief Device Descriptor helper macro.
+ */
+#define USB_DESC_DEVICE(bcdUSB, bDeviceClass, bDeviceSubClass, \
+ bDeviceProtocol, bMaxPacketSize, idVendor, \
+ idProduct, bcdDevice, iManufacturer, \
+ iProduct, iSerialNumber, bNumConfigurations) \
+ USB_DESC_BYTE(18), \
+ USB_DESC_BYTE(USB_DESCRIPTOR_DEVICE), \
+ USB_DESC_BCD(bcdUSB), \
+ USB_DESC_BYTE(bDeviceClass), \
+ USB_DESC_BYTE(bDeviceSubClass), \
+ USB_DESC_BYTE(bDeviceProtocol), \
+ USB_DESC_BYTE(bMaxPacketSize), \
+ USB_DESC_WORD(idVendor), \
+ USB_DESC_WORD(idProduct), \
+ USB_DESC_BCD(bcdDevice), \
+ USB_DESC_INDEX(iManufacturer), \
+ USB_DESC_INDEX(iProduct), \
+ USB_DESC_INDEX(iSerialNumber), \
+ USB_DESC_BYTE(bNumConfigurations)
+
+/**
+ * @brief Configuration Descriptor helper macro.
+ */
+#define USB_DESC_CONFIGURATION(wTotalLength, bNumInterfaces, \
+ bConfigurationValue, iConfiguration, \
+ bmAttributes, bMaxPower) \
+ USB_DESC_BYTE(9), \
+ USB_DESC_BYTE(USB_DESCRIPTOR_CONFIGURATION), \
+ USB_DESC_WORD(wTotalLength), \
+ USB_DESC_BYTE(bNumInterfaces), \
+ USB_DESC_BYTE(bConfigurationValue), \
+ USB_DESC_INDEX(iConfiguration), \
+ USB_DESC_BYTE(bmAttributes), \
+ USB_DESC_BYTE(bMaxPower)
+
+/**
+ * @brief Interface Descriptor helper macro.
+ */
+#define USB_DESC_INTERFACE(bInterfaceNumber, bAlternateSetting, \
+ bNumEndpoints, bInterfaceClass, \
+ bInterfaceSubClass, bInterfaceProtocol, \
+ iInterface) \
+ USB_DESC_BYTE(9), \
+ USB_DESC_BYTE(USB_DESCRIPTOR_INTERFACE), \
+ USB_DESC_BYTE(bInterfaceNumber), \
+ USB_DESC_BYTE(bAlternateSetting), \
+ USB_DESC_BYTE(bNumEndpoints), \
+ USB_DESC_BYTE(bInterfaceClass), \
+ USB_DESC_BYTE(bInterfaceSubClass), \
+ USB_DESC_BYTE(bInterfaceProtocol), \
+ USB_DESC_INDEX(iInterface)
+
+/**
+ * @brief Endpoint Descriptor helper macro.
+ */
+#define USB_DESC_ENDPOINT(bEndpointAddress, bmAttributes, wMaxPacketSize, \
+ bInterval) \
+ USB_DESC_BYTE(7), \
+ USB_DESC_BYTE(USB_DESCRIPTOR_ENDPOINT), \
+ USB_DESC_BYTE(bEndpointAddress), \
+ USB_DESC_BYTE(bmAttributes), \
+ USB_DESC_WORD(wMaxPacketSize), \
+ USB_DESC_BYTE(bInterval)
+
+/**
+ * @brief Returned by some functions to report a busy endpoint.
+ */
+#define USB_ENDPOINT_BUSY ((size_t)0xFFFFFFFF)
+
+#define USB_EP_MODE_TYPE 0x0003 /**< Endpoint type mask. */
+#define USB_EP_MODE_TYPE_CTRL 0x0000 /**< Control endpoint. */
+#define USB_EP_MODE_TYPE_ISOC 0x0001 /**< Isochronous endpoint. */
+#define USB_EP_MODE_TYPE_BULK 0x0002 /**< Bulk endpoint. */
+#define USB_EP_MODE_TYPE_INTR 0x0003 /**< Interrupt endpoint. */
+#define USB_EP_MODE_TRANSACTION 0x0000 /**< Transaction mode. */
+#define USB_EP_MODE_PACKET 0x0010 /**< Packet mode enabled. */
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -107,20 +214,10 @@ typedef enum {
} usbstate_t;
/**
- * @brief Type of an endpoint type.
- */
-typedef enum {
- EP_TYPE_CTRL = 0, /**< Control endpoint. */
- EP_TYPE_ISOC = 1, /**< Isochronous endpoint. */
- EP_TYPE_BULK = 2, /**< Bulk endpoint. */
- EP_TYPE_INTR = 3 /**< Interrupt endpoint. */
-} usbeptype_t;
-
-/**
* @brief Type of an endpoint status.
*/
typedef enum {
- EP_STATUS_DISABLED = 0, /**< Endpoint not opened. */
+ EP_STATUS_DISABLED = 0, /**< Endpoint not active. */
EP_STATUS_STALLED = 1, /**< Endpoint opened but stalled. */
EP_STATUS_ACTIVE = 2 /**< Active endpoint. */
} usbepstatus_t;
@@ -133,7 +230,8 @@ typedef enum {
USB_EP0_TX, /**< Trasmitting. */
USB_EP0_WAITING_STS, /**< Waiting status. */
USB_EP0_RX, /**< Receiving. */
- USB_EP0_SENDING_STS /**< Sending status. */
+ USB_EP0_SENDING_STS, /**< Sending status. */
+ USB_EP0_ERROR /**< Error, EP0 stalled. */
} usbep0state_t;
/**
@@ -144,7 +242,7 @@ typedef enum {
USB_EVENT_ADDRESS = 1, /**< Address assigned. */
USB_EVENT_CONFIGURED = 2, /**< Configuration selected. */
USB_EVENT_SUSPEND = 3, /**< Entering suspend mode. */
- USB_EVENT_RESUME = 4, /**< Leaving suspend mode. */
+ USB_EVENT_WAKEUP = 4, /**< Leaving suspend mode. */
USB_EVENT_STALLED = 5, /**< Endpoint 0 error, stalled. */
} usbevent_t;
@@ -219,70 +317,66 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
* @param[in] usbp pointer to the @p USBDriver object
* @return The current frame number.
*
- * @notapi
+ * @api
*/
#define usbGetFrameNumber(usbp) usb_lld_get_frame_number(usbp)
/**
- * @brief Returns the number of bytes readable from the receive packet
- * buffer.
+ * @brief Returns the status of an IN endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @return The number of bytes that are effectively available.
- * @retval 0 Data not yet available.
+ * @return The operation status.
+ * @retval FALSE Endpoint ready.
+ * @retval TRUE Endpoint transmitting.
*
* @iclass
*/
-#define usbGetReadableI(usbp, ep) usb_lld_get_readable(usbp, ep)
+#define usbGetTransmitStatusI(usbp, ep) ((usbp)->transmitting & (1 << (ep)))
/**
- * @brief Endpoint read.
- * @details The buffered packet is copied into the user buffer and then
- * the endpoint is brought to the valid state in order to allow
- * reception of more data.
+ * @brief Returns the status of an OUT endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @param[out] 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 available.
- * @retval 0 Data not yet available.
+ * @return The operation status.
+ * @retval FALSE Endpoint ready.
+ * @retval TRUE Endpoint receiving.
*
* @iclass
*/
-#define usbReadI(usbp, ep, buf, n) usb_lld_read(usbp, ep, buf, n)
+#define usbGetReceiveStatusI(usbp, ep) ((usbp)->receiving & (1 << (ep)))
/**
- * @brief Returns the number of bytes writeable to the transmit packet
- * buffer.
+ * @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 The number of bytes that can be written.
- * @retval 0 Endpoint not ready for transmission.
+ * @return Received data size.
*
* @iclass
*/
-#define usbGetWriteableI(usbp, ep) usb_lld_get_readable(usbp, ep)
+#define usbGetReceiveTransactionSizeI(usbp, ep) \
+ usb_lld_get_transaction_size(usbp, ep)
/**
- * @brief Endpoint write.
- * @details The user data is copied in the packer memory and then
- * the endpoint is brought to the valid state in order to allow
- * transmission.
+ * @brief Returns the exact size of a received packet.
+ * @pre The OUT endpoint must have been configured in packet mode
+ * in order to use this function.
*
- * @param[in] usbp pointer to the @p USBDriver object triggering the
- * callback
+ * @param[in] usbp pointer to the @p USBDriver object
* @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.
- * @retval 0 Endpoint not ready for transmission.
+ * @return Received data size.
*
* @iclass
*/
-#define usbWriteI(usbp, ep, buf, n) usb_lld_write(usbp, ep, buf, n)
+#define usbGetReceivePacketSizeI(usbp, ep) \
+ usb_lld_get_packet_size(usbp, ep)
/**
* @brief Request transfer setup.
@@ -292,14 +386,93 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] buf pointer to a buffer for the transaction data
* @param[in] n number of bytes to be transferred
- * @param[in] endcb transfer complete callback
+ * @param[in] endcb callback to be invoked after the transfer or @p NULL
*
* @api
*/
#define usbSetupTransfer(usbp, buf, n, endcb) { \
- (usbp)->usb_ep0next = (buf); \
- (usbp)->usb_ep0n = (n); \
- (usbp)->usb_ep0endcb = (endcb); \
+ (usbp)->ep0next = (buf); \
+ (usbp)->ep0n = (n); \
+ (usbp)->ep0endcb = (endcb); \
+}
+
+/**
+ * @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
+ *
+ * @special
+ */
+#define usbReadSetup(usbp, ep, buf) usb_lld_read_setup(usbp, ep, buf)
+
+/**
+ * @brief Common ISR code, usb event callback.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] evt USB event code
+ *
+ * @notapi
+ */
+#define _usb_isr_invoke_event_cb(usbp, evt) { \
+ if (((usbp)->config->event_cb) != NULL) \
+ (usbp)->config->event_cb(usbp, evt); \
+}
+
+/**
+ * @brief Common ISR code, SOF callback.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+#define _usb_isr_invoke_sof_cb(usbp) { \
+ if (((usbp)->config->sof_cb) != NULL) \
+ (usbp)->config->sof_cb(usbp); \
+}
+
+/**
+ * @brief Common ISR code, setup packet callback.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+#define _usb_isr_invoke_setup_cb(usbp, ep) { \
+ (usbp)->epc[ep]->setup_cb(usbp, ep); \
+}
+
+/**
+ * @brief Common ISR code, IN endpoint callback.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+#define _usb_isr_invoke_in_cb(usbp, ep) { \
+ (usbp)->transmitting &= ~(1 << (ep)); \
+ (usbp)->epc[ep]->in_cb(usbp, ep); \
+}
+
+/**
+ * @brief Common ISR code, OUT endpoint event.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+#define _usb_isr_invoke_out_cb(usbp, ep) { \
+ (usbp)->receiving &= ~(1 << (ep)); \
+ (usbp)->epc[ep]->out_cb(usbp, ep); \
}
/*===========================================================================*/
@@ -313,9 +486,22 @@ extern "C" {
void usbObjectInit(USBDriver *usbp);
void usbStart(USBDriver *usbp, const USBConfig *config);
void usbStop(USBDriver *usbp);
- void usbInitEndpointI(USBDriver *usbp, usbep_t ep, USBEndpointState *epp,
+ void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
const USBEndpointConfig *epcp);
+ void usbDisableEndpointsI(USBDriver *usbp);
+ void usbReadSetupI(USBDriver *usbp, usbep_t ep, uint8_t *buf);
+ size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
+ bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
+ bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep);
+ bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep);
void _usb_reset(USBDriver *usbp);
+ void _usb_ep0setup(USBDriver *usbp, usbep_t ep);
void _usb_ep0in(USBDriver *usbp, usbep_t ep);
void _usb_ep0out(USBDriver *usbp, usbep_t ep);
#ifdef __cplusplus
diff --git a/os/hal/include/usb_cdc.h b/os/hal/include/usb_cdc.h
index c1d3da3e7..a388f9f70 100644
--- a/os/hal/include/usb_cdc.h
+++ b/os/hal/include/usb_cdc.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -17,7 +18,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/**
+/*-*
* @file usb_cdc.h
* @brief USB Communication Device Class support header.
*
@@ -28,6 +29,10 @@
#ifndef _USB_CDC_H_
#define _USB_CDC_H_
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01
#define CDC_SET_COMM_FEATURE 0x02
@@ -48,6 +53,49 @@
#define CDC_SET_OPERATION_PARMS 0x32
#define CDC_GET_OPERATION_PARMS 0x33
+#define LC_STOP_1 0
+#define LC_STOP_1P5 1
+#define LC_STOP_2 2
+
+#define LC_PARITY_NONE 0
+#define LC_PARITY_ODD 1
+#define LC_PARITY_EVEN 2
+#define LC_PARITY_MARK 3
+#define LC_PARITY_SPACE 4
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Endpoint number for bulk IN.
+ */
+#if !defined(DATA_REQUEST_EP) || defined(__DOXYGEN__)
+#define DATA_REQUEST_EP 1
+#endif
+
+/**
+ * @brief Endpoint number for interrupt IN.
+ */
+#if !defined(INTERRUPT_REQUEST_EP) || defined(__DOXYGEN__)
+#define INTERRUPT_REQUEST_EP 2
+#endif
+
+/**
+ * @brief Endpoint number for bulk OUT.
+ */
+#if !defined(DATA_AVAILABLE_EP) || defined(__DOXYGEN__)
+#define DATA_AVAILABLE_EP 3
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
/**
* @brief Type of Line Coding structure.
*/
@@ -58,15 +106,13 @@ typedef struct {
uint8_t bDataBits;
} cdc_linecoding_t;
-#define LC_STOP_1 0
-#define LC_STOP_1P5 1
-#define LC_STOP_2 2
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
-#define LC_PARITY_NONE 0
-#define LC_PARITY_ODD 1
-#define LC_PARITY_EVEN 2
-#define LC_PARITY_MARK 3
-#define LC_PARITY_SPACE 4
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
#endif /* _USB_CDC_H_ */
diff --git a/os/hal/platforms/AT91SAM7/at91sam7.h b/os/hal/platforms/AT91SAM7/at91sam7.h
index a34ab62d4..e62f6a5aa 100644
--- a/os/hal/platforms/AT91SAM7/at91sam7.h
+++ b/os/hal/platforms/AT91SAM7/at91sam7.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/at91sam7_mii.c b/os/hal/platforms/AT91SAM7/at91sam7_mii.c
index 54f1b8d57..707a373b9 100644
--- a/os/hal/platforms/AT91SAM7/at91sam7_mii.c
+++ b/os/hal/platforms/AT91SAM7/at91sam7_mii.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/at91sam7_mii.h b/os/hal/platforms/AT91SAM7/at91sam7_mii.h
index c417a0d15..897a5e584 100644
--- a/os/hal/platforms/AT91SAM7/at91sam7_mii.h
+++ b/os/hal/platforms/AT91SAM7/at91sam7_mii.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/hal_lld.c b/os/hal/platforms/AT91SAM7/hal_lld.c
index 40c355659..a95293e5c 100644
--- a/os/hal/platforms/AT91SAM7/hal_lld.c
+++ b/os/hal/platforms/AT91SAM7/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/hal_lld.h b/os/hal/platforms/AT91SAM7/hal_lld.h
index c033f13e8..e40cc533f 100644
--- a/os/hal/platforms/AT91SAM7/hal_lld.h
+++ b/os/hal/platforms/AT91SAM7/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/mac_lld.c b/os/hal/platforms/AT91SAM7/mac_lld.c
index ee71b2e23..43055b94d 100644
--- a/os/hal/platforms/AT91SAM7/mac_lld.c
+++ b/os/hal/platforms/AT91SAM7/mac_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -100,9 +101,9 @@ static void serve_interrupt(void) {
if ((isr & AT91C_EMAC_RCOMP) || (rsr & RSR_BITS)) {
if (rsr & AT91C_EMAC_REC) {
chSysLockFromIsr();
- chSemResetI(&ETH1.md_rdsem, 0);
+ chSemResetI(&ETH1.rdsem, 0);
#if CH_USE_EVENTS
- chEvtBroadcastI(&ETH1.md_rdevent);
+ chEvtBroadcastI(&ETH1.rdevent);
#endif
chSysUnlockFromIsr();
}
@@ -112,7 +113,7 @@ static void serve_interrupt(void) {
if ((isr & AT91C_EMAC_TCOMP) || (tsr & TSR_BITS)) {
if (tsr & AT91C_EMAC_COMP) {
chSysLockFromIsr();
- chSemResetI(&ETH1.md_tdsem, 0);
+ chSemResetI(&ETH1.tdsem, 0);
chSysUnlockFromIsr();
}
AT91C_BASE_EMAC->EMAC_TSR = TSR_BITS;
@@ -291,9 +292,9 @@ msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
else
edp->w2 = W2_T_LOCKED | W2_T_USED | W2_T_LAST_BUFFER;
chSysUnlock();
- tdp->td_offset = 0;
- tdp->td_size = EMAC_TRANSMIT_BUFFERS_SIZE;
- tdp->td_physdesc = edp;
+ tdp->offset = 0;
+ tdp->size = EMAC_TRANSMIT_BUFFERS_SIZE;
+ tdp->physdesc = edp;
return RDY_OK;
}
@@ -315,13 +316,13 @@ size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
uint8_t *buf,
size_t size) {
- if (size > tdp->td_size - tdp->td_offset)
- size = tdp->td_size - tdp->td_offset;
+ if (size > tdp->size - tdp->offset)
+ size = tdp->size - tdp->offset;
if (size > 0) {
- memcpy((uint8_t *)(tdp->td_physdesc->w1 & W1_T_ADDRESS_MASK) +
- tdp->td_offset,
+ memcpy((uint8_t *)(tdp->physdesc->w1 & W1_T_ADDRESS_MASK) +
+ tdp->offset,
buf, size);
- tdp->td_offset += size;
+ tdp->offset += size;
}
return size;
}
@@ -337,9 +338,9 @@ size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) {
chSysLock();
- tdp->td_physdesc->w2 = (tdp->td_physdesc->w2 &
+ tdp->physdesc->w2 = (tdp->physdesc->w2 &
~(W2_T_LOCKED | W2_T_USED | W2_T_LENGTH_MASK)) |
- tdp->td_offset;
+ tdp->offset;
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
chSysUnlock();
}
@@ -400,9 +401,9 @@ restart:
* End Of Frame found.
*/
if (rxptr->w2 & W2_R_FRAME_END) {
- rdp->rd_offset = 0;
- rdp->rd_size = rxptr->w2 & W2_T_LENGTH_MASK;
- rdp->rd_physdesc = edp;
+ rdp->offset = 0;
+ rdp->size = rxptr->w2 & W2_T_LENGTH_MASK;
+ rdp->physdesc = edp;
return RDY_OK;
}
@@ -435,11 +436,11 @@ restart:
size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
uint8_t *buf,
size_t size) {
- if (size > rdp->rd_size - rdp->rd_offset)
- size = rdp->rd_size - rdp->rd_offset;
+ if (size > rdp->size - rdp->offset)
+ size = rdp->size - rdp->offset;
if (size > 0) {
- uint8_t *src = (uint8_t *)(rdp->rd_physdesc->w1 & W1_R_ADDRESS_MASK) +
- rdp->rd_offset;
+ uint8_t *src = (uint8_t *)(rdp->physdesc->w1 & W1_R_ADDRESS_MASK) +
+ rdp->offset;
uint8_t *limit = &rb[EMAC_RECEIVE_DESCRIPTORS * EMAC_RECEIVE_BUFFERS_SIZE];
if (src >= limit)
src -= EMAC_RECEIVE_DESCRIPTORS * EMAC_RECEIVE_BUFFERS_SIZE;
@@ -449,7 +450,7 @@ size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
}
else
memcpy(buf, src, size);
- rdp->rd_offset += size;
+ rdp->offset += size;
}
return size;
}
@@ -465,7 +466,7 @@ size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
*/
void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) {
bool_t done;
- EMACDescriptor *edp = rdp->rd_physdesc;
+ EMACDescriptor *edp = rdp->physdesc;
unsigned n = EMAC_RECEIVE_DESCRIPTORS;
do {
diff --git a/os/hal/platforms/AT91SAM7/mac_lld.h b/os/hal/platforms/AT91SAM7/mac_lld.h
index 21503dd53..9f30e0426 100644
--- a/os/hal/platforms/AT91SAM7/mac_lld.h
+++ b/os/hal/platforms/AT91SAM7/mac_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -66,7 +67,7 @@
#define W1_T_ADDRESS_MASK 0xFFFFFFFF
#define W2_T_LENGTH_MASK 0x000007FF
-#define W2_T_LOCKED 0x00000800 /* Not an EMAC flag, used by the driver */
+#define W2_T_LOCKED 0x00000800 /* Not an EMAC flag. */
#define W2_T_RFU1 0x00003000
#define W2_T_LAST_BUFFER 0x00008000
#define W2_T_NO_CRC 0x00010000
@@ -130,10 +131,10 @@ typedef struct {
* @brief Structure representing a MAC driver.
*/
typedef struct {
- Semaphore md_tdsem; /**< Transmit semaphore. */
- Semaphore md_rdsem; /**< Receive semaphore. */
+ Semaphore tdsem; /**< Transmit semaphore. */
+ Semaphore rdsem; /**< Receive semaphore. */
#if CH_USE_EVENTS
- EventSource md_rdevent; /**< Receive event source. */
+ EventSource rdevent; /**< Receive event source. */
#endif
/* End of the mandatory fields.*/
} MACDriver;
@@ -142,22 +143,23 @@ typedef struct {
* @brief Structure representing a transmit descriptor.
*/
typedef struct {
- size_t td_offset; /**< Current write offset. */
- size_t td_size; /**< Available space size. */
+ size_t offset; /**< Current write offset. */
+ size_t size; /**< Available space size. */
/* End of the mandatory fields.*/
- EMACDescriptor *td_physdesc; /**< Pointer to the physical
- descriptor. */
+ EMACDescriptor *physdesc; /**< Pointer to the physical
+ descriptor. */
} MACTransmitDescriptor;
/**
* @brief Structure representing a receive descriptor.
*/
typedef struct {
- size_t rd_offset; /**< Current read offset. */
- size_t rd_size; /**< Available data size. */
+ size_t offset; /**< Current read offset. */
+ size_t size; /**< Available data size. */
/* End of the mandatory fields.*/
- EMACDescriptor *rd_physdesc; /**< Pointer to the first descriptor
- of the buffers chain. */
+ EMACDescriptor *physdesc; /**< Pointer to the first
+ descriptor of the buffers
+ chain. */
} MACReceiveDescriptor;
/*===========================================================================*/
diff --git a/os/hal/platforms/AT91SAM7/pal_lld.c b/os/hal/platforms/AT91SAM7/pal_lld.c
index 4b43cd8d6..0e2136da1 100644
--- a/os/hal/platforms/AT91SAM7/pal_lld.c
+++ b/os/hal/platforms/AT91SAM7/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/pal_lld.h b/os/hal/platforms/AT91SAM7/pal_lld.h
index afcc7c238..9c5796a40 100644
--- a/os/hal/platforms/AT91SAM7/pal_lld.h
+++ b/os/hal/platforms/AT91SAM7/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -154,9 +155,7 @@ typedef AT91PS_PIO ioportid_t;
*
* @notapi
*/
-#define pal_lld_writeport(port, bits) { \
- (port)->PIO_ODSR = (bits); \
-}
+#define pal_lld_writeport(port, bits) ((port)->PIO_ODSR = (bits))
/**
* @brief Sets a bits mask on a I/O port.
@@ -168,9 +167,7 @@ typedef AT91PS_PIO ioportid_t;
*
* @notapi
*/
-#define pal_lld_setport(port, bits) { \
- (port)->PIO_SODR = (bits); \
-}
+#define pal_lld_setport(port, bits) ((port)->PIO_SODR = (bits))
/**
* @brief Clears a bits mask on a I/O port.
@@ -182,9 +179,7 @@ typedef AT91PS_PIO ioportid_t;
*
* @notapi
*/
-#define pal_lld_clearport(port, bits) { \
- (port)->PIO_CODR = (bits); \
-}
+#define pal_lld_clearport(port, bits) ((port)->PIO_CODR = (bits))
/**
* @brief Writes a group of bits.
@@ -200,11 +195,10 @@ typedef AT91PS_PIO ioportid_t;
*
* @notapi
*/
-#define pal_lld_writegroup(port, mask, offset, bits) { \
- (port)->PIO_OWER = (mask) << (offset); \
- (port)->PIO_ODSR = (bits) << (offset); \
- (port)->PIO_OWDR = (mask) << (offset); \
-}
+#define pal_lld_writegroup(port, mask, offset, bits) \
+ ((port)->PIO_OWER = (mask) << (offset), \
+ (port)->PIO_ODSR = (bits) << (offset), \
+ (port)->PIO_OWDR = (mask) << (offset))
/**
* @brief Pads group mode setup.
diff --git a/os/hal/platforms/AT91SAM7/platform.dox b/os/hal/platforms/AT91SAM7/platform.dox
index af4816486..84f19fac5 100644
--- a/os/hal/platforms/AT91SAM7/platform.dox
+++ b/os/hal/platforms/AT91SAM7/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -42,7 +43,7 @@
*/
/**
- * @defgroup AT91SAM7_MAC AT91SAM7 EMAC Support
+ * @defgroup AT91SAM7_MAC AT91SAM7 MAC Support
* @details The AT91SAM7 MAC driver supports the EMAC peripheral.
*
* @section at91sam7_mac_1 Supported HW resources
@@ -62,7 +63,7 @@
*/
/**
- * @defgroup AT91SAM7_PAL AT91SAM7 PIO Support
+ * @defgroup AT91SAM7_PAL AT91SAM7 PAL Support
* @details The AT91SAM7 PAL driver supports the PIO peripherals.
*
* @section at91sam7_pal_1 Supported HW resources
@@ -99,26 +100,7 @@
*/
/**
- * @defgroup AT91SAM7_SPI AT91SAM7 SPI Support
- * @details The SPI driver supports the AT91SAM7 SPI peripherals using DMA
- * channels for maximum performance.
- *
- * @section at91sam7_spi_1 Supported HW resources
- * - SPI1.
- * - SPI2.
- * .
- * @section at91sam7_spi_2 AT91SAM7 SPI driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Each SPI can be independently enabled and programmed. Unused
- * peripherals are left in low power mode.
- * - Programmable interrupt priority levels for each SPI.
- * - DMA is used for receiving and transmitting.
- * .
- * @ingroup AT91SAM7
- */
-
-/**
- * @defgroup AT91SAM7_SERIAL AT91SAM7 USART Support (buffered)
+ * @defgroup AT91SAM7_SERIAL AT91SAM7 Serial Support
* @details The AT91SAM7 Serial driver uses the USART/UART peripherals in a
* buffered, interrupt driven, implementation.
*
@@ -137,3 +119,22 @@
* .
* @ingroup AT91SAM7
*/
+
+/**
+ * @defgroup AT91SAM7_SPI AT91SAM7 SPI Support
+ * @details The SPI driver supports the AT91SAM7 SPI peripherals using DMA
+ * channels for maximum performance.
+ *
+ * @section at91sam7_spi_1 Supported HW resources
+ * - SPI1.
+ * - SPI2.
+ * .
+ * @section at91sam7_spi_2 AT91SAM7 SPI driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Each SPI can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable interrupt priority levels for each SPI.
+ * - DMA is used for receiving and transmitting.
+ * .
+ * @ingroup AT91SAM7
+ */
diff --git a/os/hal/platforms/AT91SAM7/serial_lld.c b/os/hal/platforms/AT91SAM7/serial_lld.c
index f34f2b6d8..eff24a804 100644
--- a/os/hal/platforms/AT91SAM7/serial_lld.c
+++ b/os/hal/platforms/AT91SAM7/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -225,7 +226,7 @@ static void notify3(GenericQueue *qp) {
/**
* @brief USART0 interrupt handler.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(USART0IrqHandler) {
@@ -331,7 +332,7 @@ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
AIC_EnableIT(AT91C_ID_US1);
}
#endif
- /* Note - no explicit start for SD3 (DBGU_UART) since it's not included
+ /* Note - no explicit start for SD3 (DBGU_UART) since it's not included
in the AIC or PMC.*/
}
usart_init(sdp, config);
diff --git a/os/hal/platforms/AT91SAM7/serial_lld.h b/os/hal/platforms/AT91SAM7/serial_lld.h
index 94aca128b..20b47562f 100644
--- a/os/hal/platforms/AT91SAM7/serial_lld.h
+++ b/os/hal/platforms/AT91SAM7/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AT91SAM7/spi_lld.c b/os/hal/platforms/AT91SAM7/spi_lld.c
index 316ff65c9..218793d1e 100644
--- a/os/hal/platforms/AT91SAM7/spi_lld.c
+++ b/os/hal/platforms/AT91SAM7/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -55,7 +56,7 @@ SPIDriver SPID2;
* somewhere.
* @note This buffer size also limits the maximum transfer size, 512B,
* for @p spiReceive() and @p spiIgnore(). @p spiSend() and
- * @p spiExchange are not affected.
+ * @p spiExchange are not affected.
*/
static const uint16_t idle_buf[] = {
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
@@ -97,7 +98,7 @@ static const uint16_t idle_buf[] = {
/*===========================================================================*/
/**
- * @brief Initializes a SPI device.
+ * @brief Initializes a SPI device.
*/
static void spi_init(AT91PS_SPI spi) {
@@ -116,19 +117,19 @@ static void spi_init(AT91PS_SPI spi) {
__attribute__((noinline))
#endif
/**
- * @brief Shared interrupt handling code.
+ * @brief Shared interrupt handling code.
*
* @param[in] spip pointer to the @p SPIDriver object
*/
static void spi_lld_serve_interrupt(SPIDriver *spip) {
- uint32_t sr = spip->spd_spi->SPI_SR;
+ uint32_t sr = spip->spi->SPI_SR;
if ((sr & AT91C_SPI_ENDRX) != 0) {
- (void)spip->spd_spi->SPI_RDR; /* Clears eventual overflow.*/
- spip->spd_spi->SPI_PTCR = AT91C_PDC_RXTDIS |
+ (void)spip->spi->SPI_RDR; /* Clears eventual overflow.*/
+ spip->spi->SPI_PTCR = AT91C_PDC_RXTDIS |
AT91C_PDC_TXTDIS; /* PDC disabled. */
- spip->spd_spi->SPI_IDR = AT91C_SPI_ENDRX; /* Interrupt disabled. */
- spip->spd_spi->SPI_CR = AT91C_SPI_SPIDIS; /* SPI disabled. */
+ spip->spi->SPI_IDR = AT91C_SPI_ENDRX; /* Interrupt disabled. */
+ spip->spi->SPI_CR = AT91C_SPI_SPIDIS; /* SPI disabled. */
/* Portable SPI ISR code defined in the high level driver, note, it is
a macro.*/
_spi_isr_code(spip);
@@ -182,7 +183,7 @@ void spi_lld_init(void) {
#if AT91SAM7_SPI_USE_SPI0
spiObjectInit(&SPID1);
- SPID1.spd_spi = AT91C_BASE_SPI0;
+ SPID1.spi = AT91C_BASE_SPI0;
spi_init(AT91C_BASE_SPI0);
AT91C_BASE_PIOA->PIO_PDR = SPI0_MISO | SPI0_MOSI | SPI0_SCK;
AT91C_BASE_PIOA->PIO_ASR = SPI0_MISO | SPI0_MOSI | SPI0_SCK;
@@ -194,7 +195,7 @@ void spi_lld_init(void) {
#if AT91SAM7_SPI_USE_SPI1
spiObjectInit(&SPID2);
- SPID2.spd_spi = AT91C_BASE_SPI1;
+ SPID2.spi = AT91C_BASE_SPI1;
spi_init(AT91C_BASE_SPI1);
AT91C_BASE_PIOA->PIO_PDR = SPI1_MISO | SPI1_MOSI | SPI1_SCK;
AT91C_BASE_PIOA->PIO_BSR = SPI1_MISO | SPI1_MOSI | SPI1_SCK;
@@ -214,7 +215,7 @@ void spi_lld_init(void) {
*/
void spi_lld_start(SPIDriver *spip) {
- if (spip->spd_state == SPI_STOP) {
+ if (spip->state == SPI_STOP) {
#if AT91SAM7_SPI_USE_SPI0
if (&SPID1 == spip) {
/* Clock activation.*/
@@ -233,7 +234,7 @@ void spi_lld_start(SPIDriver *spip) {
#endif
}
/* Configuration.*/
- spip->spd_spi->SPI_CSR[0] = spip->spd_config->spc_csr;
+ spip->spi->SPI_CSR[0] = spip->config->csr;
}
/**
@@ -245,7 +246,7 @@ void spi_lld_start(SPIDriver *spip) {
*/
void spi_lld_stop(SPIDriver *spip) {
- if (spip->spd_state != SPI_STOP) {
+ if (spip->state != SPI_STOP) {
#if AT91SAM7_SPI_USE_SPI0
if (&SPID1 == spip) {
AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_SPI0);
@@ -270,7 +271,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
- palClearPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -283,7 +284,7 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
- palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -299,13 +300,13 @@ void spi_lld_unselect(SPIDriver *spip) {
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
- spip->spd_spi->SPI_TCR = n;
- spip->spd_spi->SPI_RCR = n;
- spip->spd_spi->SPI_TPR = (AT91_REG)idle_buf;
- spip->spd_spi->SPI_RPR = (AT91_REG)idle_buf;
- spip->spd_spi->SPI_IER = AT91C_SPI_ENDRX;
- spip->spd_spi->SPI_CR = AT91C_SPI_SPIEN;
- spip->spd_spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
+ spip->spi->SPI_TCR = n;
+ spip->spi->SPI_RCR = n;
+ spip->spi->SPI_TPR = (AT91_REG)idle_buf;
+ spip->spi->SPI_RPR = (AT91_REG)idle_buf;
+ spip->spi->SPI_IER = AT91C_SPI_ENDRX;
+ spip->spi->SPI_CR = AT91C_SPI_SPIEN;
+ spip->spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
}
/**
@@ -323,13 +324,13 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
- spip->spd_spi->SPI_TCR = n;
- spip->spd_spi->SPI_RCR = n;
- spip->spd_spi->SPI_TPR = (AT91_REG)txbuf;
- spip->spd_spi->SPI_RPR = (AT91_REG)rxbuf;
- spip->spd_spi->SPI_IER = AT91C_SPI_ENDRX;
- spip->spd_spi->SPI_CR = AT91C_SPI_SPIEN;
- spip->spd_spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
+ spip->spi->SPI_TCR = n;
+ spip->spi->SPI_RCR = n;
+ spip->spi->SPI_TPR = (AT91_REG)txbuf;
+ spip->spi->SPI_RPR = (AT91_REG)rxbuf;
+ spip->spi->SPI_IER = AT91C_SPI_ENDRX;
+ spip->spi->SPI_CR = AT91C_SPI_SPIEN;
+ spip->spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
}
/**
@@ -344,13 +345,13 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
- spip->spd_spi->SPI_TCR = n;
- spip->spd_spi->SPI_RCR = n;
- spip->spd_spi->SPI_TPR = (AT91_REG)txbuf;
- spip->spd_spi->SPI_RPR = (AT91_REG)idle_buf;
- spip->spd_spi->SPI_IER = AT91C_SPI_ENDRX;
- spip->spd_spi->SPI_CR = AT91C_SPI_SPIEN;
- spip->spd_spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
+ spip->spi->SPI_TCR = n;
+ spip->spi->SPI_RCR = n;
+ spip->spi->SPI_TPR = (AT91_REG)txbuf;
+ spip->spi->SPI_RPR = (AT91_REG)idle_buf;
+ spip->spi->SPI_IER = AT91C_SPI_ENDRX;
+ spip->spi->SPI_CR = AT91C_SPI_SPIEN;
+ spip->spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
}
/**
@@ -365,13 +366,13 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
- spip->spd_spi->SPI_TCR = n;
- spip->spd_spi->SPI_RCR = n;
- spip->spd_spi->SPI_TPR = (AT91_REG)idle_buf;
- spip->spd_spi->SPI_RPR = (AT91_REG)rxbuf;
- spip->spd_spi->SPI_IER = AT91C_SPI_ENDRX;
- spip->spd_spi->SPI_CR = AT91C_SPI_SPIEN;
- spip->spd_spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
+ spip->spi->SPI_TCR = n;
+ spip->spi->SPI_RCR = n;
+ spip->spi->SPI_TPR = (AT91_REG)idle_buf;
+ spip->spi->SPI_RPR = (AT91_REG)rxbuf;
+ spip->spi->SPI_IER = AT91C_SPI_ENDRX;
+ spip->spi->SPI_CR = AT91C_SPI_SPIEN;
+ spip->spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
}
/**
@@ -388,11 +389,11 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
*/
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
- spip->spd_spi->SPI_CR = AT91C_SPI_SPIEN;
- spip->spd_spi->SPI_TDR = frame;
- while ((spip->spd_spi->SPI_SR & AT91C_SPI_RDRF) == 0)
+ spip->spi->SPI_CR = AT91C_SPI_SPIEN;
+ spip->spi->SPI_TDR = frame;
+ while ((spip->spi->SPI_SR & AT91C_SPI_RDRF) == 0)
;
- return spip->spd_spi->SPI_RDR;
+ return spip->spi->SPI_RDR;
}
#endif /* HAL_USE_SPI */
diff --git a/os/hal/platforms/AT91SAM7/spi_lld.h b/os/hal/platforms/AT91SAM7/spi_lld.h
index 3b0bfaaba..8949a1703 100644
--- a/os/hal/platforms/AT91SAM7/spi_lld.h
+++ b/os/hal/platforms/AT91SAM7/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -127,20 +128,20 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
- ioportid_t spc_ssport;
+ ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
- uint16_t spc_sspad;
+ uint16_t sspad;
/**
* @brief SPI Chip Select Register initialization data.
*/
- uint32_t spc_csr;
+ uint32_t csr;
} SPIConfig;
/**
@@ -150,25 +151,25 @@ struct SPIDriver {
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
@@ -178,7 +179,7 @@ struct SPIDriver {
/**
* @brief Pointer to the SPIx registers block.
*/
- AT91PS_SPI spd_spi;
+ AT91PS_SPI spi;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/AVR/hal_lld.c b/os/hal/platforms/AVR/hal_lld.c
index a3d3f4ab8..421401158 100644
--- a/os/hal/platforms/AVR/hal_lld.c
+++ b/os/hal/platforms/AVR/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AVR/hal_lld.h b/os/hal/platforms/AVR/hal_lld.h
index 647c2f142..c3d65f167 100644
--- a/os/hal/platforms/AVR/hal_lld.h
+++ b/os/hal/platforms/AVR/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/AVR/platform.dox b/os/hal/platforms/AVR/platform.dox
index 9b8cf3e6b..bc29954b6 100644
--- a/os/hal/platforms/AVR/platform.dox
+++ b/os/hal/platforms/AVR/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -35,7 +36,7 @@
*/
/**
- * @defgroup AVR_SERIAL AVR USART Support (buffered)
+ * @defgroup AVR_SERIAL AVR Serial Support
* @details The AVR Serial driver uses the USART peripherals in a
* buffered, interrupt driven, implementation.
*
diff --git a/os/hal/platforms/AVR/serial_lld.c b/os/hal/platforms/AVR/serial_lld.c
index f78abac18..a61d6b0c2 100644
--- a/os/hal/platforms/AVR/serial_lld.c
+++ b/os/hal/platforms/AVR/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -154,7 +155,7 @@ static void usart1_deinit(void) {
/**
* @brief USART0 RX interrupt handler.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(USART0_RX_vect) {
uint8_t sra;
@@ -174,7 +175,7 @@ CH_IRQ_HANDLER(USART0_RX_vect) {
/**
* @brief USART0 TX interrupt handler.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(USART0_UDRE_vect) {
msg_t b;
@@ -182,7 +183,7 @@ CH_IRQ_HANDLER(USART0_UDRE_vect) {
CH_IRQ_PROLOGUE();
chSysLockFromIsr();
- b = sdRequestDataI(&SER1);
+ b = sdRequestDataI(&SD1);
chSysUnlockFromIsr();
if (b < Q_OK)
UCSR0B &= ~(1 << UDRIE);
@@ -197,7 +198,7 @@ CH_IRQ_HANDLER(USART0_UDRE_vect) {
/**
* @brief USART1 RX interrupt handler.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(USART1_RX_vect) {
uint8_t sra;
@@ -217,7 +218,7 @@ CH_IRQ_HANDLER(USART1_RX_vect) {
/**
* @brief USART1 TX interrupt handler.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(USART1_UDRE_vect) {
msg_t b;
diff --git a/os/hal/platforms/AVR/serial_lld.h b/os/hal/platforms/AVR/serial_lld.h
index 4a2ff843a..f660b7d2d 100644
--- a/os/hal/platforms/AVR/serial_lld.h
+++ b/os/hal/platforms/AVR/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -105,7 +106,7 @@ typedef struct {
* @brief Macro for baud rate computation.
* @note Make sure the final baud rate is within tolerance.
*/
-#define UBRR(b) ((F_CPU / (b << 4)) - 1)
+#define UBRR(b) (((F_CPU / b) >> 4) - 1)
/*===========================================================================*/
/* External declarations. */
diff --git a/os/hal/platforms/LPC11xx/core_cm0.h b/os/hal/platforms/LPC11xx/core_cm0.h
index af27881d4..662099a21 100644
--- a/os/hal/platforms/LPC11xx/core_cm0.h
+++ b/os/hal/platforms/LPC11xx/core_cm0.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/gpt_lld.c b/os/hal/platforms/LPC11xx/gpt_lld.c
new file mode 100644
index 000000000..df90ac630
--- /dev/null
+++ b/os/hal/platforms/LPC11xx/gpt_lld.c
@@ -0,0 +1,342 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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 LPC11xx/gpt_lld.c
+ * @brief LPC11xx GPT subsystem low level driver source.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT1 driver identifier.
+ * @note The driver GPT1 allocates the complex timer CT16B0 when enabled.
+ */
+#if LPC11xx_GPT_USE_CT16B0 || defined(__DOXYGEN__)
+GPTDriver GPTD1;
+#endif
+
+/**
+ * @brief GPT2 driver identifier.
+ * @note The driver GPT2 allocates the timer CT16B1 when enabled.
+ */
+#if LPC11xx_GPT_USE_CT16B1 || defined(__DOXYGEN__)
+GPTDriver GPTD2;
+#endif
+
+/**
+ * @brief GPT3 driver identifier.
+ * @note The driver GPT3 allocates the timer CT32B0 when enabled.
+ */
+#if LPC11xx_GPT_USE_CT32B0 || defined(__DOXYGEN__)
+GPTDriver GPTD3;
+#endif
+
+/**
+ * @brief GPT4 driver identifier.
+ * @note The driver GPT4 allocates the timer CT32B1 when enabled.
+ */
+#if LPC11xx_GPT_USE_CT32B1 || defined(__DOXYGEN__)
+GPTDriver GPTD4;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Shared IRQ handler.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ */
+static void gpt_lld_serve_interrupt(GPTDriver *gptp) {
+
+ gptp->tmr->IR = 1; /* Clear interrupt on match MR0.*/
+ if (gptp->state == GPT_ONESHOT) {
+ gptp->state = GPT_READY; /* Back in GPT_READY state. */
+ gpt_lld_stop_timer(gptp); /* Timer automatically stopped. */
+ }
+ gptp->config->callback(gptp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if LPC11xx_GPT_USE_CT16B0
+/**
+ * @brief CT16B0 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector80) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD1);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC11xx_GPT_USE_CT16B0 */
+
+#if LPC11xx_GPT_USE_CT16B1
+/**
+ * @brief CT16B1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector84) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD2);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC11xx_GPT_USE_CT16B0 */
+
+#if LPC11xx_GPT_USE_CT32B0
+/**
+ * @brief CT32B0 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector88) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD3);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC11xx_GPT_USE_CT32B0 */
+
+#if LPC11xx_GPT_USE_CT32B1
+/**
+ * @brief CT32B1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector8C) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD4);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC11xx_GPT_USE_CT32B1 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level GPT driver initialization.
+ *
+ * @notapi
+ */
+void gpt_lld_init(void) {
+
+#if LPC11xx_GPT_USE_CT16B0
+ /* Driver initialization.*/
+ GPTD1.tmr = LPC_TMR16B0;
+ gptObjectInit(&GPTD1);
+#endif
+
+#if LPC11xx_GPT_USE_CT16B1
+ /* Driver initialization.*/
+ GPTD2.tmr = LPC_TMR16B1;
+ gptObjectInit(&GPTD2);
+#endif
+
+#if LPC11xx_GPT_USE_CT32B0
+ /* Driver initialization.*/
+ GPTD3.tmr = LPC_TMR32B0;
+ gptObjectInit(&GPTD3);
+#endif
+
+#if LPC11xx_GPT_USE_CT32B1
+ /* Driver initialization.*/
+ GPTD4.tmr = LPC_TMR32B1;
+ gptObjectInit(&GPTD4);
+#endif
+}
+
+/**
+ * @brief Configures and activates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_start(GPTDriver *gptp) {
+ uint32_t pr;
+
+ if (gptp->state == GPT_STOP) {
+ /* Clock activation.*/
+#if LPC11xx_GPT_USE_CT16B0
+ if (&GPTD1 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 7);
+ NVICEnableVector(TIMER_16_0_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+#if LPC11xx_GPT_USE_CT16B1
+ if (&GPTD2 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);
+ NVICEnableVector(TIMER_16_1_IRQn, CORTEX_PRIORITY_MASK(3));
+ }
+#endif
+#if LPC11xx_GPT_USE_CT32B0
+ if (&GPTD3 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 9);
+ NVICEnableVector(TIMER_32_0_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+#if LPC11xx_GPT_USE_CT32B1
+ if (&GPTD4 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10);
+ NVICEnableVector(TIMER_32_1_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+ }
+
+ /* Prescaler value calculation.*/
+ pr = (uint16_t)((LPC11xx_SYSCLK / gptp->config->frequency) - 1);
+ chDbgAssert(((uint32_t)(pr + 1) * gptp->config->frequency) == LPC11xx_SYSCLK,
+ "gpt_lld_start(), #1", "invalid frequency");
+
+ /* Timer configuration.*/
+ gptp->tmr->PR = pr;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+}
+
+/**
+ * @brief Deactivates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop(GPTDriver *gptp) {
+
+ if (gptp->state == GPT_READY) {
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+
+#if LPC11xx_GPT_USE_CT16B0
+ if (&GPTD1 == gptp) {
+ NVICDisableVector(TIMER_16_0_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 7);
+ }
+#endif
+#if LPC11xx_GPT_USE_CT16B1
+ if (&GPTD2 == gptp) {
+ NVICDisableVector(TIMER_16_1_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 8);
+ }
+#endif
+#if LPC11xx_GPT_USE_CT32B0
+ if (&GPTD3 == gptp) {
+ NVICDisableVector(TIMER_32_0_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 9);
+ }
+#endif
+#if LPC11xx_GPT_USE_CT32B1
+ if (&GPTD4 == gptp) {
+ NVICDisableVector(TIMER_32_1_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 10);
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tmr->MR0 = interval - 1;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 3; /* IRQ and clr TC on match MR0. */
+ gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
+ gptp->tmr->TCR = 1; /* Timer enabled. */
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop_timer(GPTDriver *gptp) {
+
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+}
+
+/**
+ * @brief Starts the timer in one shot mode and waits for completion.
+ * @details This function specifically polls the timer waiting for completion
+ * in order to not have extra delays caused by interrupt servicing,
+ * this function is only recommended for short delays.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tmr->MR0 = interval - 1;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 4; /* Stop TC on match MR0. */
+ gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
+ gptp->tmr->TCR = 1; /* Timer enabled. */
+ while (gptp->tmr->TCR & 1)
+ ;
+}
+
+#endif /* HAL_USE_GPT */
+
+/** @} */
diff --git a/os/hal/platforms/LPC11xx/gpt_lld.h b/os/hal/platforms/LPC11xx/gpt_lld.h
new file mode 100644
index 000000000..1aa1e3b90
--- /dev/null
+++ b/os/hal/platforms/LPC11xx/gpt_lld.h
@@ -0,0 +1,208 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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 LPC11xx/gpt_lld.h
+ * @brief LPC11xx GPT subsystem low level driver header.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#ifndef _GPT_LLD_H_
+#define _GPT_LLD_H_
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT1 driver enable switch.
+ * @details If set to @p TRUE the support for GPT1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC11xx_GPT_USE_CT16B0) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_USE_CT16B0 TRUE
+#endif
+
+/**
+ * @brief GPT2 driver enable switch.
+ * @details If set to @p TRUE the support for GPT2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC11xx_GPT_USE_CT16B1) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_USE_CT16B1 TRUE
+#endif
+
+/**
+ * @brief GPT3 driver enable switch.
+ * @details If set to @p TRUE the support for GPT3 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC11xx_GPT_USE_CT32B0) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_USE_CT32B0 TRUE
+#endif
+
+/**
+ * @brief GPT4 driver enable switch.
+ * @details If set to @p TRUE the support for GPT4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC11xx_GPT_USE_CT32B1) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_USE_CT32B1 TRUE
+#endif
+
+/**
+ * @brief GPT1 interrupt priority level setting.
+ */
+#if !defined(LPC11xx_GPT_CT16B0_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_CT16B0_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT2 interrupt priority level setting.
+ */
+#if !defined(LPC11xx_GPT_CT16B1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_CT16B1_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT3 interrupt priority level setting.
+ */
+#if !defined(LPC11xx_GPT_CT32B0_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_CT32B0_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT4 interrupt priority level setting.
+ */
+#if !defined(LPC11xx_GPT_CT32B1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC11xx_GPT_CT32B1_IRQ_PRIORITY 2
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !LPC11xx_GPT_USE_CT16B0 && !LPC11xx_GPT_USE_CT16B1 && \
+ !LPC11xx_GPT_USE_CT32B0 && !LPC11xx_GPT_USE_CT32B1
+#error "GPT driver activated but no CT peripheral assigned"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT frequency type.
+ */
+typedef uint32_t gptfreq_t;
+
+/**
+ * @brief GPT counter type.
+ */
+typedef uint32_t gptcnt_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ gptfreq_t frequency;
+ /**
+ * @brief Timer callback pointer.
+ * @note This callback is invoked on GPT counter events.
+ */
+ gptcallback_t callback;
+ /* End of the mandatory fields.*/
+} GPTConfig;
+
+/**
+ * @brief Structure representing a GPT driver.
+ */
+struct GPTDriver {
+ /**
+ * @brief Driver state.
+ */
+ gptstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const GPTConfig *config;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the CTxxBy registers block.
+ */
+ LPC_TMR_TypeDef *tmr;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if LPC11xx_GPT_USE_CT16B0 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD1;
+#endif
+
+#if LPC11xx_GPT_USE_CT16B1 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD2;
+#endif
+
+#if LPC11xx_GPT_USE_CT32B0 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD3;
+#endif
+
+#if LPC11xx_GPT_USE_CT32B1 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD4;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void gpt_lld_init(void);
+ void gpt_lld_start(GPTDriver *gptp);
+ void gpt_lld_stop(GPTDriver *gptp);
+ void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period);
+ void gpt_lld_stop_timer(GPTDriver *gptp);
+ void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_GPT */
+
+#endif /* _GPT_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/LPC11xx/hal_lld.c b/os/hal/platforms/LPC11xx/hal_lld.c
index 8bb79f866..89db29491 100644
--- a/os/hal/platforms/LPC11xx/hal_lld.c
+++ b/os/hal/platforms/LPC11xx/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/hal_lld.h b/os/hal/platforms/LPC11xx/hal_lld.h
index f94b058fd..267ce9105 100644
--- a/os/hal/platforms/LPC11xx/hal_lld.h
+++ b/os/hal/platforms/LPC11xx/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/pal_lld.c b/os/hal/platforms/LPC11xx/pal_lld.c
index c8d831a82..6ce6ba876 100644
--- a/os/hal/platforms/LPC11xx/pal_lld.c
+++ b/os/hal/platforms/LPC11xx/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/pal_lld.h b/os/hal/platforms/LPC11xx/pal_lld.h
index 4201f5114..d60b4ef71 100644
--- a/os/hal/platforms/LPC11xx/pal_lld.h
+++ b/os/hal/platforms/LPC11xx/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/platform.dox b/os/hal/platforms/LPC11xx/platform.dox
index 19dd542ae..593a82fdf 100644
--- a/os/hal/platforms/LPC11xx/platform.dox
+++ b/os/hal/platforms/LPC11xx/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -43,7 +44,25 @@
*/
/**
- * @defgroup LPC11xx_PAL LPC11xx GPIO Support
+ * @defgroup LPC11xx_GPT LPC11xx GPT Support
+ * @details The LPC11xx GPT driver uses the CTxxBy peripherals.
+ *
+ * @section lpc11xx_gpt_1 Supported HW resources
+ * - CT16B0.
+ * - CT16B1.
+ * - CT32B0.
+ * - CT32B1.
+ * .
+ * @section lpc11xx_gpt_2 LPC11xx GPT driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable CTxxBy interrupts priority level.
+ * .
+ * @ingroup LPC11xx
+ */
+
+/**
+ * @defgroup LPC11xx_PAL LPC11xx PAL Support
* @details The LPC11xx PAL driver uses the GPIO peripherals.
*
* @section lpc11xx_pal_1 Supported HW resources
@@ -79,7 +98,26 @@
*/
/**
- * @defgroup LPC11xx_SPI LPC11xx SSP Support
+ * @defgroup LPC11xx_SERIAL LPC11xx Serial Support
+ * @details The LPC11xx Serial driver uses the UART peripheral in a
+ * buffered, interrupt driven, implementation. The serial driver
+ * also takes advantage of the LPC11xx UARTs deep hardware buffers.
+ *
+ * @section lpc11xx_serial_1 Supported HW resources
+ * The serial driver can support any of the following hardware resources:
+ * - UART.
+ * .
+ * @section lpc11xx_serial_2 LPC11xx Serial driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Fully interrupt driven.
+ * - Programmable priority level.
+ * - Takes advantage of the input and output FIFOs.
+ * .
+ * @ingroup LPC11xx
+ */
+
+/**
+ * @defgroup LPC11xx_SPI LPC11xx SPI Support
* @details The SPI driver supports the LPC11xx SSP peripherals in an interrupt
* driven implementation.
* @note Being the SPI a fast peripheral, much care must be taken to
@@ -100,22 +138,3 @@
* .
* @ingroup LPC11xx
*/
-
-/**
- * @defgroup LPC11xx_SERIAL LPC11xx UART Support (buffered)
- * @details The LPC11xx Serial driver uses the UART peripheral in a
- * buffered, interrupt driven, implementation. The serial driver
- * also takes advantage of the LPC11xx UARTs deep hardware buffers.
- *
- * @section lpc11xx_serial_1 Supported HW resources
- * The serial driver can support any of the following hardware resources:
- * - UART.
- * .
- * @section lpc11xx_serial_2 LPC11xx Serial driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Fully interrupt driven.
- * - Programmable priority level.
- * - Takes advantage of the input and output FIFOs.
- * .
- * @ingroup LPC11xx
- */
diff --git a/os/hal/platforms/LPC11xx/platform.mk b/os/hal/platforms/LPC11xx/platform.mk
index ade33695f..4f0d19547 100644
--- a/os/hal/platforms/LPC11xx/platform.mk
+++ b/os/hal/platforms/LPC11xx/platform.mk
@@ -1,5 +1,6 @@
# List of all the LPC11xx platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/LPC11xx/hal_lld.c \
+ ${CHIBIOS}/os/hal/platforms/LPC11xx/gpt_lld.c \
${CHIBIOS}/os/hal/platforms/LPC11xx/pal_lld.c \
${CHIBIOS}/os/hal/platforms/LPC11xx/serial_lld.c \
${CHIBIOS}/os/hal/platforms/LPC11xx/spi_lld.c
diff --git a/os/hal/platforms/LPC11xx/serial_lld.c b/os/hal/platforms/LPC11xx/serial_lld.c
index ecd080eaf..269a5a8e5 100644
--- a/os/hal/platforms/LPC11xx/serial_lld.c
+++ b/os/hal/platforms/LPC11xx/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/serial_lld.h b/os/hal/platforms/LPC11xx/serial_lld.h
index a2e8acc4b..ffe9a8ae6 100644
--- a/os/hal/platforms/LPC11xx/serial_lld.h
+++ b/os/hal/platforms/LPC11xx/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC11xx/spi_lld.c b/os/hal/platforms/LPC11xx/spi_lld.c
index 47766088c..5704b17f3 100644
--- a/os/hal/platforms/LPC11xx/spi_lld.c
+++ b/os/hal/platforms/LPC11xx/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -58,27 +59,27 @@ SPIDriver SPID2;
* @param[in] spip pointer to the @p SPIDriver object
*/
static void ssp_fifo_preload(SPIDriver *spip) {
- LPC_SSP_TypeDef *ssp = spip->spd_ssp;
- uint32_t n = spip->spd_txcnt > LPC11xx_SSP_FIFO_DEPTH ?
- LPC11xx_SSP_FIFO_DEPTH : spip->spd_txcnt;
+ LPC_SSP_TypeDef *ssp = spip->ssp;
+ uint32_t n = spip->txcnt > LPC11xx_SSP_FIFO_DEPTH ?
+ LPC11xx_SSP_FIFO_DEPTH : spip->txcnt;
while(((ssp->SR & SR_TNF) != 0) && (n > 0)) {
- if (spip->spd_txptr != NULL) {
+ if (spip->txptr != NULL) {
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
- const uint16_t *p = spip->spd_txptr;
+ const uint16_t *p = spip->txptr;
ssp->DR = *p++;
- spip->spd_txptr = p;
+ spip->txptr = p;
}
else {
- const uint8_t *p = spip->spd_txptr;
+ const uint8_t *p = spip->txptr;
ssp->DR = *p++;
- spip->spd_txptr = p;
+ spip->txptr = p;
}
}
else
ssp->DR = 0xFFFFFFFF;
n--;
- spip->spd_txcnt--;
+ spip->txcnt--;
}
}
@@ -88,7 +89,7 @@ static void ssp_fifo_preload(SPIDriver *spip) {
* @param[in] spip pointer to the @p SPIDriver object
*/
static void spi_serve_interrupt(SPIDriver *spip) {
- LPC_SSP_TypeDef *ssp = spip->spd_ssp;
+ LPC_SSP_TypeDef *ssp = spip->ssp;
if ((ssp->MIS & MIS_ROR) != 0) {
/* The overflow condition should never happen because priority is given
@@ -97,22 +98,22 @@ static void spi_serve_interrupt(SPIDriver *spip) {
}
ssp->ICR = ICR_RT | ICR_ROR;
while ((ssp->SR & SR_RNE) != 0) {
- if (spip->spd_rxptr != NULL) {
+ if (spip->rxptr != NULL) {
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
- uint16_t *p = spip->spd_rxptr;
+ uint16_t *p = spip->rxptr;
*p++ = ssp->DR;
- spip->spd_rxptr = p;
+ spip->rxptr = p;
}
else {
- uint8_t *p = spip->spd_rxptr;
+ uint8_t *p = spip->rxptr;
*p++ = ssp->DR;
- spip->spd_rxptr = p;
+ spip->rxptr = p;
}
}
else
(void)ssp->DR;
- if (--spip->spd_rxcnt == 0) {
- chDbgAssert(spip->spd_txcnt == 0,
+ if (--spip->rxcnt == 0) {
+ chDbgAssert(spip->txcnt == 0,
"spi_serve_interrupt(), #1", "counter out of synch");
/* Stops the IRQ sources.*/
ssp->IMSC = 0;
@@ -123,7 +124,7 @@ static void spi_serve_interrupt(SPIDriver *spip) {
}
}
ssp_fifo_preload(spip);
- if (spip->spd_txcnt == 0)
+ if (spip->txcnt == 0)
ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_RX;
}
@@ -176,7 +177,7 @@ void spi_lld_init(void) {
#if LPC11xx_SPI_USE_SSP0
spiObjectInit(&SPID1);
- SPID1.spd_ssp = LPC_SSP0;
+ SPID1.ssp = LPC_SSP0;
LPC_IOCON->SCK_LOC = LPC11xx_SPI_SCK0_SELECTOR;
#if LPC11xx_SPI_SCK0_SELECTOR == SCK0_IS_PIO0_10
LPC_IOCON->JTAG_TCK_PIO0_10 = 0xC2; /* SCK0 without resistors. */
@@ -191,7 +192,7 @@ void spi_lld_init(void) {
#if LPC11xx_SPI_USE_SSP1
spiObjectInit(&SPID2);
- SPID2.spd_ssp = LPC_SSP1;
+ SPID2.ssp = LPC_SSP1;
LPC_IOCON->PIO2_1 = 0xC2; /* SCK1 without resistors. */
LPC_IOCON->PIO2_2 = 0xC2; /* MISO1 without resistors. */
LPC_IOCON->PIO2_3 = 0xC2; /* MOSI1 without resistors. */
@@ -207,7 +208,7 @@ void spi_lld_init(void) {
*/
void spi_lld_start(SPIDriver *spip) {
- if (spip->spd_state == SPI_STOP) {
+ if (spip->state == SPI_STOP) {
/* Clock activation.*/
#if LPC11xx_SPI_USE_SSP0
if (&SPID1 == spip) {
@@ -229,11 +230,11 @@ void spi_lld_start(SPIDriver *spip) {
#endif
}
/* Configuration.*/
- spip->spd_ssp->CR1 = 0;
- spip->spd_ssp->ICR = ICR_RT | ICR_ROR;
- spip->spd_ssp->CR0 = spip->spd_config->spc_cr0;
- spip->spd_ssp->CPSR = spip->spd_config->spc_cpsr;
- spip->spd_ssp->CR1 = CR1_SSE;
+ spip->ssp->CR1 = 0;
+ spip->ssp->ICR = ICR_RT | ICR_ROR;
+ spip->ssp->CR0 = spip->config->cr0;
+ spip->ssp->CPSR = spip->config->cpsr;
+ spip->ssp->CR1 = CR1_SSE;
}
/**
@@ -245,10 +246,10 @@ void spi_lld_start(SPIDriver *spip) {
*/
void spi_lld_stop(SPIDriver *spip) {
- if (spip->spd_state != SPI_STOP) {
- spip->spd_ssp->CR1 = 0;
- spip->spd_ssp->CR0 = 0;
- spip->spd_ssp->CPSR = 0;
+ if (spip->state != SPI_STOP) {
+ spip->ssp->CR1 = 0;
+ spip->ssp->CR0 = 0;
+ spip->ssp->CPSR = 0;
#if LPC11xx_SPI_USE_SSP0
if (&SPID1 == spip) {
LPC_SYSCON->PRESETCTRL &= ~1;
@@ -277,7 +278,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
- palClearPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -290,7 +291,7 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
- palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -306,11 +307,11 @@ void spi_lld_unselect(SPIDriver *spip) {
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -331,11 +332,11 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -353,11 +354,11 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -375,11 +376,11 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -396,10 +397,10 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
*/
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
- spip->spd_ssp->DR = (uint32_t)frame;
- while ((spip->spd_ssp->SR & SR_RNE) == 0)
+ spip->ssp->DR = (uint32_t)frame;
+ while ((spip->ssp->SR & SR_RNE) == 0)
;
- return (uint16_t)spip->spd_ssp->DR;
+ return (uint16_t)spip->ssp->DR;
}
#endif /* HAL_USE_SPI */
diff --git a/os/hal/platforms/LPC11xx/spi_lld.h b/os/hal/platforms/LPC11xx/spi_lld.h
index e0525387a..47df7d94b 100644
--- a/os/hal/platforms/LPC11xx/spi_lld.h
+++ b/os/hal/platforms/LPC11xx/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -194,13 +195,13 @@
/**
* @brief SSP0 clock.
*/
-#define LPC11xx_SERIAL_SSP0_PCLK \
+#define LPC11xx_SERIAL_SSP0_PCLK \
(LPC11xx_MAINCLK / LPC11xx_SERIAL_SSP0CLKDIV)
/**
* @brief SSP1 clock.
*/
-#define LPC11xx_SERIAL_SSP1_PCLK \
+#define LPC11xx_SERIAL_SSP1_PCLK \
(LPC11xx_MAINCLK / LPC11xx_SERIAL_SSP1CLKDIV)
/*===========================================================================*/
@@ -227,24 +228,24 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
- ioportid_t spc_ssport;
+ ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
- uint16_t spc_sspad;
+ uint16_t sspad;
/**
* @brief SSP CR0 initialization data.
*/
- uint16_t spc_cr0;
+ uint16_t cr0;
/**
* @brief SSP CPSR initialization data.
*/
- uint32_t spc_cpsr;
+ uint32_t cpsr;
} SPIConfig;
/**
@@ -254,25 +255,25 @@ struct SPIDriver {
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
@@ -282,23 +283,23 @@ struct SPIDriver {
/**
* @brief Pointer to the SSP registers block.
*/
- LPC_SSP_TypeDef *spd_ssp;
+ LPC_SSP_TypeDef *ssp;
/**
* @brief Number of bytes yet to be received.
*/
- uint32_t spd_rxcnt;
+ uint32_t rxcnt;
/**
* @brief Receive pointer or @p NULL.
*/
- void *spd_rxptr;
+ void *rxptr;
/**
* @brief Number of bytes yet to be transmitted.
*/
- uint32_t spd_txcnt;
+ uint32_t txcnt;
/**
* @brief Transmit pointer or @p NULL.
*/
- const void *spd_txptr;
+ const void *txptr;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/LPC13xx/core_cm3.h b/os/hal/platforms/LPC13xx/core_cm3.h
index 5c75ec859..387221bc6 100644
--- a/os/hal/platforms/LPC13xx/core_cm3.h
+++ b/os/hal/platforms/LPC13xx/core_cm3.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/gpt_lld.c b/os/hal/platforms/LPC13xx/gpt_lld.c
new file mode 100644
index 000000000..7d6961889
--- /dev/null
+++ b/os/hal/platforms/LPC13xx/gpt_lld.c
@@ -0,0 +1,342 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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 LPC13xx/gpt_lld.c
+ * @brief LPC13xx GPT subsystem low level driver source.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT1 driver identifier.
+ * @note The driver GPT1 allocates the complex timer CT16B0 when enabled.
+ */
+#if LPC13xx_GPT_USE_CT16B0 || defined(__DOXYGEN__)
+GPTDriver GPTD1;
+#endif
+
+/**
+ * @brief GPT2 driver identifier.
+ * @note The driver GPT2 allocates the timer CT16B1 when enabled.
+ */
+#if LPC13xx_GPT_USE_CT16B1 || defined(__DOXYGEN__)
+GPTDriver GPTD2;
+#endif
+
+/**
+ * @brief GPT3 driver identifier.
+ * @note The driver GPT3 allocates the timer CT32B0 when enabled.
+ */
+#if LPC13xx_GPT_USE_CT32B0 || defined(__DOXYGEN__)
+GPTDriver GPTD3;
+#endif
+
+/**
+ * @brief GPT4 driver identifier.
+ * @note The driver GPT4 allocates the timer CT32B1 when enabled.
+ */
+#if LPC13xx_GPT_USE_CT32B1 || defined(__DOXYGEN__)
+GPTDriver GPTD4;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Shared IRQ handler.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ */
+static void gpt_lld_serve_interrupt(GPTDriver *gptp) {
+
+ gptp->tmr->IR = 1; /* Clear interrupt on match MR0.*/
+ if (gptp->state == GPT_ONESHOT) {
+ gptp->state = GPT_READY; /* Back in GPT_READY state. */
+ gpt_lld_stop_timer(gptp); /* Timer automatically stopped. */
+ }
+ gptp->config->callback(gptp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if LPC13xx_GPT_USE_CT16B0
+/**
+ * @brief CT16B0 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(VectorE4) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD1);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC13xx_GPT_USE_CT16B0 */
+
+#if LPC13xx_GPT_USE_CT16B1
+/**
+ * @brief CT16B1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(VectorE8) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD2);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC13xx_GPT_USE_CT16B0 */
+
+#if LPC13xx_GPT_USE_CT32B0
+/**
+ * @brief CT32B0 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(VectorEC) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD3);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC13xx_GPT_USE_CT32B0 */
+
+#if LPC13xx_GPT_USE_CT32B1
+/**
+ * @brief CT32B1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(VectorF0) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD4);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC13xx_GPT_USE_CT32B1 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level GPT driver initialization.
+ *
+ * @notapi
+ */
+void gpt_lld_init(void) {
+
+#if LPC13xx_GPT_USE_CT16B0
+ /* Driver initialization.*/
+ GPTD1.tmr = LPC_TMR16B0;
+ gptObjectInit(&GPTD1);
+#endif
+
+#if LPC13xx_GPT_USE_CT16B1
+ /* Driver initialization.*/
+ GPTD2.tmr = LPC_TMR16B1;
+ gptObjectInit(&GPTD2);
+#endif
+
+#if LPC13xx_GPT_USE_CT32B0
+ /* Driver initialization.*/
+ GPTD3.tmr = LPC_TMR32B0;
+ gptObjectInit(&GPTD3);
+#endif
+
+#if LPC13xx_GPT_USE_CT32B1
+ /* Driver initialization.*/
+ GPTD4.tmr = LPC_TMR32B1;
+ gptObjectInit(&GPTD4);
+#endif
+}
+
+/**
+ * @brief Configures and activates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_start(GPTDriver *gptp) {
+ uint32_t pr;
+
+ if (gptp->state == GPT_STOP) {
+ /* Clock activation.*/
+#if LPC13xx_GPT_USE_CT16B0
+ if (&GPTD1 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 7);
+ NVICEnableVector(TIMER_16_0_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+#if LPC13xx_GPT_USE_CT16B1
+ if (&GPTD2 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);
+ NVICEnableVector(TIMER_16_1_IRQn, CORTEX_PRIORITY_MASK(3));
+ }
+#endif
+#if LPC13xx_GPT_USE_CT32B0
+ if (&GPTD3 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 9);
+ NVICEnableVector(TIMER_32_0_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+#if LPC13xx_GPT_USE_CT32B1
+ if (&GPTD4 == gptp) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10);
+ NVICEnableVector(TIMER_32_1_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+ }
+
+ /* Prescaler value calculation.*/
+ pr = (uint16_t)((LPC13xx_SYSCLK / gptp->config->frequency) - 1);
+ chDbgAssert(((uint32_t)(pr + 1) * gptp->config->frequency) == LPC13xx_SYSCLK,
+ "gpt_lld_start(), #1", "invalid frequency");
+
+ /* Timer configuration.*/
+ gptp->tmr->PR = pr;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+}
+
+/**
+ * @brief Deactivates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop(GPTDriver *gptp) {
+
+ if (gptp->state == GPT_READY) {
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+
+#if LPC13xx_GPT_USE_CT16B0
+ if (&GPTD1 == gptp) {
+ NVICDisableVector(TIMER_16_0_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 7);
+ }
+#endif
+#if LPC13xx_GPT_USE_CT16B1
+ if (&GPTD2 == gptp) {
+ NVICDisableVector(TIMER_16_1_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 8);
+ }
+#endif
+#if LPC13xx_GPT_USE_CT32B0
+ if (&GPTD3 == gptp) {
+ NVICDisableVector(TIMER_32_0_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 9);
+ }
+#endif
+#if LPC13xx_GPT_USE_CT32B1
+ if (&GPTD4 == gptp) {
+ NVICDisableVector(TIMER_32_1_IRQn);
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 10);
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tmr->MR0 = interval - 1;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 3; /* IRQ and clr TC on match MR0. */
+ gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
+ gptp->tmr->TCR = 1; /* Timer enabled. */
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop_timer(GPTDriver *gptp) {
+
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+}
+
+/**
+ * @brief Starts the timer in one shot mode and waits for completion.
+ * @details This function specifically polls the timer waiting for completion
+ * in order to not have extra delays caused by interrupt servicing,
+ * this function is only recommended for short delays.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tmr->MR0 = interval - 1;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 4; /* Stop TC on match MR0. */
+ gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
+ gptp->tmr->TCR = 1; /* Timer enabled. */
+ while (gptp->tmr->TCR & 1)
+ ;
+}
+
+#endif /* HAL_USE_GPT */
+
+/** @} */
diff --git a/os/hal/platforms/LPC13xx/gpt_lld.h b/os/hal/platforms/LPC13xx/gpt_lld.h
new file mode 100644
index 000000000..e4a53224b
--- /dev/null
+++ b/os/hal/platforms/LPC13xx/gpt_lld.h
@@ -0,0 +1,212 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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 LPC13xx/gpt_lld.h
+ * @brief LPC13xx GPT subsystem low level driver header.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#ifndef _GPT_LLD_H_
+#define _GPT_LLD_H_
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT1 driver enable switch.
+ * @details If set to @p TRUE the support for GPT1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC13xx_GPT_USE_CT16B0) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_USE_CT16B0 TRUE
+#endif
+
+/**
+ * @brief GPT2 driver enable switch.
+ * @details If set to @p TRUE the support for GPT2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC13xx_GPT_USE_CT16B1) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_USE_CT16B1 TRUE
+#endif
+
+/**
+ * @brief GPT3 driver enable switch.
+ * @details If set to @p TRUE the support for GPT3 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC13xx_GPT_USE_CT32B0) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_USE_CT32B0 TRUE
+#endif
+
+/**
+ * @brief GPT4 driver enable switch.
+ * @details If set to @p TRUE the support for GPT4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC13xx_GPT_USE_CT32B1) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_USE_CT32B1 TRUE
+#endif
+
+/**
+ * @brief GPT1 interrupt priority level setting.
+ */
+#if !defined(LPC13xx_GPT_CT16B0_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_CT16B0_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT2 interrupt priority level setting.
+ */
+#if !defined(LPC13xx_GPT_CT16B1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_CT16B1_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT3 interrupt priority level setting.
+ */
+#if !defined(LPC13xx_GPT_CT32B0_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_CT32B0_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT4 interrupt priority level setting.
+ */
+#if !defined(LPC13xx_GPT_CT32B1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC13xx_GPT_CT32B1_IRQ_PRIORITY 2
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !LPC13xx_GPT_USE_CT16B0 && !LPC13xx_GPT_USE_CT16B1 && \
+ !LPC13xx_GPT_USE_CT32B0 && !LPC13xx_GPT_USE_CT32B1
+#error "GPT driver activated but no CT peripheral assigned"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT frequency type.
+ */
+typedef uint32_t gptfreq_t;
+
+/**
+ * @brief GPT counter type.
+ */
+typedef uint32_t gptcnt_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ gptfreq_t frequency;
+ /**
+ * @brief Timer callback pointer.
+ * @note This callback is invoked on GPT counter events.
+ */
+ gptcallback_t callback;
+ /* End of the mandatory fields.*/
+} GPTConfig;
+
+/**
+ * @brief Structure representing a GPT driver.
+ */
+struct GPTDriver {
+ /**
+ * @brief Driver state.
+ */
+ gptstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const GPTConfig *config;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Timer base clock.
+ */
+ uint32_t clock;
+ /**
+ * @brief Pointer to the CTxxBy registers block.
+ */
+ LPC_TMR_TypeDef *tmr;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if LPC13xx_GPT_USE_CT16B0 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD1;
+#endif
+
+#if LPC13xx_GPT_USE_CT16B1 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD2;
+#endif
+
+#if LPC13xx_GPT_USE_CT32B0 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD3;
+#endif
+
+#if LPC13xx_GPT_USE_CT32B1 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD4;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void gpt_lld_init(void);
+ void gpt_lld_start(GPTDriver *gptp);
+ void gpt_lld_stop(GPTDriver *gptp);
+ void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period);
+ void gpt_lld_stop_timer(GPTDriver *gptp);
+ void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_GPT */
+
+#endif /* _GPT_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/LPC13xx/hal_lld.c b/os/hal/platforms/LPC13xx/hal_lld.c
index 5babb8d2d..da09ebf43 100644
--- a/os/hal/platforms/LPC13xx/hal_lld.c
+++ b/os/hal/platforms/LPC13xx/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/hal_lld.h b/os/hal/platforms/LPC13xx/hal_lld.h
index ff7445df9..0f6b1f611 100644
--- a/os/hal/platforms/LPC13xx/hal_lld.h
+++ b/os/hal/platforms/LPC13xx/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/pal_lld.c b/os/hal/platforms/LPC13xx/pal_lld.c
index f80faaa24..6a66f1ead 100644
--- a/os/hal/platforms/LPC13xx/pal_lld.c
+++ b/os/hal/platforms/LPC13xx/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/pal_lld.h b/os/hal/platforms/LPC13xx/pal_lld.h
index 2c5a1d118..bbf4db0e8 100644
--- a/os/hal/platforms/LPC13xx/pal_lld.h
+++ b/os/hal/platforms/LPC13xx/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/platform.dox b/os/hal/platforms/LPC13xx/platform.dox
index 7b1e09a60..00b3dd1ad 100644
--- a/os/hal/platforms/LPC13xx/platform.dox
+++ b/os/hal/platforms/LPC13xx/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -43,7 +44,25 @@
*/
/**
- * @defgroup LPC13xx_PAL LPC13xx GPIO Support
+ * @defgroup LPC13xx_GPT LPC13xx GPT Support
+ * @details The LPC13xx GPT driver uses the CTxxBy peripherals.
+ *
+ * @section lpc13xx_gpt_1 Supported HW resources
+ * - CT16B0.
+ * - CT16B1.
+ * - CT32B0.
+ * - CT32B1.
+ * .
+ * @section lpc13xx_gpt_2 LPC13xx GPT driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable CTxxBy interrupts priority level.
+ * .
+ * @ingroup LPC13xx
+ */
+
+/**
+ * @defgroup LPC13xx_PAL LPC13xx PAL Support
* @details The LPC13xx PAL driver uses the GPIO peripherals.
*
* @section lpc13xx_pal_1 Supported HW resources
@@ -79,7 +98,26 @@
*/
/**
- * @defgroup LPC13xx_SPI LPC13xx SSP Support
+ * @defgroup LPC13xx_SERIAL LPC13xx Serial Support
+ * @details The LPC13xx Serial driver uses the UART peripheral in a
+ * buffered, interrupt driven, implementation. The serial driver
+ * also takes advantage of the LPC13xx UARTs deep hardware buffers.
+ *
+ * @section lpc13xx_serial_1 Supported HW resources
+ * The serial driver can support any of the following hardware resources:
+ * - UART.
+ * .
+ * @section lpc13xx_serial_2 LPC13xx Serial driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Fully interrupt driven.
+ * - Programmable priority level.
+ * - Takes advantage of the input and output FIFOs.
+ * .
+ * @ingroup LPC13xx
+ */
+
+/**
+ * @defgroup LPC13xx_SPI LPC13xx SPI Support
* @details The SPI driver supports the LPC13xx SSP peripherals in an interrupt
* driven implementation.
* @note Being the SPI a fast peripheral, much care must be taken to
@@ -100,22 +138,3 @@
* .
* @ingroup LPC13xx
*/
-
-/**
- * @defgroup LPC13xx_SERIAL LPC13xx UART Support (buffered)
- * @details The LPC13xx Serial driver uses the UART peripheral in a
- * buffered, interrupt driven, implementation. The serial driver
- * also takes advantage of the LPC13xx UARTs deep hardware buffers.
- *
- * @section lpc13xx_serial_1 Supported HW resources
- * The serial driver can support any of the following hardware resources:
- * - UART.
- * .
- * @section lpc13xx_serial_2 LPC13xx Serial driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Fully interrupt driven.
- * - Programmable priority level.
- * - Takes advantage of the input and output FIFOs.
- * .
- * @ingroup LPC13xx
- */
diff --git a/os/hal/platforms/LPC13xx/platform.mk b/os/hal/platforms/LPC13xx/platform.mk
index 66c39058e..1171af7d7 100644
--- a/os/hal/platforms/LPC13xx/platform.mk
+++ b/os/hal/platforms/LPC13xx/platform.mk
@@ -1,5 +1,6 @@
# List of all the LPC13xx platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/LPC13xx/hal_lld.c \
+ ${CHIBIOS}/os/hal/platforms/LPC13xx/gpt_lld.c \
${CHIBIOS}/os/hal/platforms/LPC13xx/pal_lld.c \
${CHIBIOS}/os/hal/platforms/LPC13xx/serial_lld.c \
${CHIBIOS}/os/hal/platforms/LPC13xx/spi_lld.c
diff --git a/os/hal/platforms/LPC13xx/serial_lld.c b/os/hal/platforms/LPC13xx/serial_lld.c
index b0f53d97a..b4f7844c4 100644
--- a/os/hal/platforms/LPC13xx/serial_lld.c
+++ b/os/hal/platforms/LPC13xx/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/serial_lld.h b/os/hal/platforms/LPC13xx/serial_lld.h
index 3636f224a..e00f44de9 100644
--- a/os/hal/platforms/LPC13xx/serial_lld.h
+++ b/os/hal/platforms/LPC13xx/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC13xx/spi_lld.c b/os/hal/platforms/LPC13xx/spi_lld.c
index 1a98a7a15..ec207f19e 100644
--- a/os/hal/platforms/LPC13xx/spi_lld.c
+++ b/os/hal/platforms/LPC13xx/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -53,27 +54,27 @@ SPIDriver SPID1;
* @param[in] spip pointer to the @p SPIDriver object
*/
static void ssp_fifo_preload(SPIDriver *spip) {
- LPC_SSP_TypeDef *ssp = spip->spd_ssp;
- uint32_t n = spip->spd_txcnt > LPC13xx_SSP_FIFO_DEPTH ?
- LPC13xx_SSP_FIFO_DEPTH : spip->spd_txcnt;
+ LPC_SSP_TypeDef *ssp = spip->ssp;
+ uint32_t n = spip->txcnt > LPC13xx_SSP_FIFO_DEPTH ?
+ LPC13xx_SSP_FIFO_DEPTH : spip->txcnt;
while(((ssp->SR & SR_TNF) != 0) && (n > 0)) {
- if (spip->spd_txptr != NULL) {
+ if (spip->txptr != NULL) {
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
- const uint16_t *p = spip->spd_txptr;
+ const uint16_t *p = spip->txptr;
ssp->DR = *p++;
- spip->spd_txptr = p;
+ spip->txptr = p;
}
else {
- const uint8_t *p = spip->spd_txptr;
+ const uint8_t *p = spip->txptr;
ssp->DR = *p++;
- spip->spd_txptr = p;
+ spip->txptr = p;
}
}
else
ssp->DR = 0xFFFFFFFF;
n--;
- spip->spd_txcnt--;
+ spip->txcnt--;
}
}
@@ -83,7 +84,7 @@ static void ssp_fifo_preload(SPIDriver *spip) {
* @param[in] spip pointer to the @p SPIDriver object
*/
static void spi_serve_interrupt(SPIDriver *spip) {
- LPC_SSP_TypeDef *ssp = spip->spd_ssp;
+ LPC_SSP_TypeDef *ssp = spip->ssp;
if ((ssp->MIS & MIS_ROR) != 0) {
/* The overflow condition should never happen because priority is given
@@ -92,22 +93,22 @@ static void spi_serve_interrupt(SPIDriver *spip) {
}
ssp->ICR = ICR_RT | ICR_ROR;
while ((ssp->SR & SR_RNE) != 0) {
- if (spip->spd_rxptr != NULL) {
+ if (spip->rxptr != NULL) {
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
- uint16_t *p = spip->spd_rxptr;
+ uint16_t *p = spip->rxptr;
*p++ = ssp->DR;
- spip->spd_rxptr = p;
+ spip->rxptr = p;
}
else {
- uint8_t *p = spip->spd_rxptr;
+ uint8_t *p = spip->rxptr;
*p++ = ssp->DR;
- spip->spd_rxptr = p;
+ spip->rxptr = p;
}
}
else
(void)ssp->DR;
- if (--spip->spd_rxcnt == 0) {
- chDbgAssert(spip->spd_txcnt == 0,
+ if (--spip->rxcnt == 0) {
+ chDbgAssert(spip->txcnt == 0,
"spi_serve_interrupt(), #1", "counter out of synch");
/* Stops the IRQ sources.*/
ssp->IMSC = 0;
@@ -118,7 +119,7 @@ static void spi_serve_interrupt(SPIDriver *spip) {
}
}
ssp_fifo_preload(spip);
- if (spip->spd_txcnt == 0)
+ if (spip->txcnt == 0)
ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_RX;
}
@@ -155,7 +156,7 @@ void spi_lld_init(void) {
#if LPC13xx_SPI_USE_SSP0
spiObjectInit(&SPID1);
- SPID1.spd_ssp = LPC_SSP;
+ SPID1.ssp = LPC_SSP;
LPC_IOCON->SCKLOC = LPC13xx_SPI_SCK0_SELECTOR;
#if LPC13xx_SPI_SCK0_SELECTOR == SCK0_IS_PIO0_10
LPC_IOCON->JTAG_TCK_PIO0_10 = 0xC2; /* SCK0 without resistors. */
@@ -178,7 +179,7 @@ void spi_lld_init(void) {
*/
void spi_lld_start(SPIDriver *spip) {
- if (spip->spd_state == SPI_STOP) {
+ if (spip->state == SPI_STOP) {
/* Clock activation.*/
#if LPC13xx_SPI_USE_SSP0
if (&SPID1 == spip) {
@@ -191,11 +192,11 @@ void spi_lld_start(SPIDriver *spip) {
#endif
}
/* Configuration.*/
- spip->spd_ssp->CR1 = 0;
- spip->spd_ssp->ICR = ICR_RT | ICR_ROR;
- spip->spd_ssp->CR0 = spip->spd_config->spc_cr0;
- spip->spd_ssp->CPSR = spip->spd_config->spc_cpsr;
- spip->spd_ssp->CR1 = CR1_SSE;
+ spip->ssp->CR1 = 0;
+ spip->ssp->ICR = ICR_RT | ICR_ROR;
+ spip->ssp->CR0 = spip->config->cr0;
+ spip->ssp->CPSR = spip->config->cpsr;
+ spip->ssp->CR1 = CR1_SSE;
}
/**
@@ -207,10 +208,10 @@ void spi_lld_start(SPIDriver *spip) {
*/
void spi_lld_stop(SPIDriver *spip) {
- if (spip->spd_state != SPI_STOP) {
- spip->spd_ssp->CR1 = 0;
- spip->spd_ssp->CR0 = 0;
- spip->spd_ssp->CPSR = 0;
+ if (spip->state != SPI_STOP) {
+ spip->ssp->CR1 = 0;
+ spip->ssp->CR0 = 0;
+ spip->ssp->CPSR = 0;
#if LPC13xx_SPI_USE_SSP0
if (&SPID1 == spip) {
LPC_SYSCON->PRESETCTRL &= ~1;
@@ -231,7 +232,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
- palClearPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -244,7 +245,7 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
- palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -260,11 +261,11 @@ void spi_lld_unselect(SPIDriver *spip) {
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -285,11 +286,11 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -307,11 +308,11 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -329,11 +330,11 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -350,10 +351,10 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
*/
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
- spip->spd_ssp->DR = (uint32_t)frame;
- while ((spip->spd_ssp->SR & SR_RNE) == 0)
+ spip->ssp->DR = (uint32_t)frame;
+ while ((spip->ssp->SR & SR_RNE) == 0)
;
- return (uint16_t)spip->spd_ssp->DR;
+ return (uint16_t)spip->ssp->DR;
}
#endif /* HAL_USE_SPI */
diff --git a/os/hal/platforms/LPC13xx/spi_lld.h b/os/hal/platforms/LPC13xx/spi_lld.h
index 153ce815b..b5f63f40b 100644
--- a/os/hal/platforms/LPC13xx/spi_lld.h
+++ b/os/hal/platforms/LPC13xx/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -167,7 +168,7 @@
/**
* @brief SSP0 clock.
*/
-#define LPC13xx_SERIAL_SSP0_PCLK \
+#define LPC13xx_SERIAL_SSP0_PCLK \
(LPC13xx_MAINCLK / LPC13xx_SERIAL_SSP0CLKDIV)
/*===========================================================================*/
@@ -194,24 +195,24 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
- ioportid_t spc_ssport;
+ ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
- uint16_t spc_sspad;
+ uint16_t sspad;
/**
* @brief SSP CR0 initialization data.
*/
- uint16_t spc_cr0;
+ uint16_t cr0;
/**
* @brief SSP CPSR initialization data.
*/
- uint32_t spc_cpsr;
+ uint32_t cpsr;
} SPIConfig;
/**
@@ -221,25 +222,25 @@ struct SPIDriver {
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
@@ -249,23 +250,23 @@ struct SPIDriver {
/**
* @brief Pointer to the SSP registers block.
*/
- LPC_SSP_TypeDef *spd_ssp;
+ LPC_SSP_TypeDef *ssp;
/**
* @brief Number of bytes yet to be received.
*/
- uint32_t spd_rxcnt;
+ uint32_t rxcnt;
/**
* @brief Receive pointer or @p NULL.
*/
- void *spd_rxptr;
+ void *rxptr;
/**
* @brief Number of bytes yet to be transmitted.
*/
- uint32_t spd_txcnt;
+ uint32_t txcnt;
/**
* @brief Transmit pointer or @p NULL.
*/
- const void *spd_txptr;
+ const void *txptr;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/LPC214x/hal_lld.c b/os/hal/platforms/LPC214x/hal_lld.c
index 3f63e65c1..942b60777 100644
--- a/os/hal/platforms/LPC214x/hal_lld.c
+++ b/os/hal/platforms/LPC214x/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/hal_lld.h b/os/hal/platforms/LPC214x/hal_lld.h
index 54d91b881..70349ae30 100644
--- a/os/hal/platforms/LPC214x/hal_lld.h
+++ b/os/hal/platforms/LPC214x/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/lpc214x.h b/os/hal/platforms/LPC214x/lpc214x.h
index f2ddac376..b30996568 100644
--- a/os/hal/platforms/LPC214x/lpc214x.h
+++ b/os/hal/platforms/LPC214x/lpc214x.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/pal_lld.c b/os/hal/platforms/LPC214x/pal_lld.c
index 4d6f14fa9..2e503c631 100644
--- a/os/hal/platforms/LPC214x/pal_lld.c
+++ b/os/hal/platforms/LPC214x/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/pal_lld.h b/os/hal/platforms/LPC214x/pal_lld.h
index 8f9d3a457..1a45cd6a9 100644
--- a/os/hal/platforms/LPC214x/pal_lld.h
+++ b/os/hal/platforms/LPC214x/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -193,11 +194,10 @@ typedef FIO * ioportid_t;
*
* @notapi
*/
-#define pal_lld_writegroup(port, mask, offset, bits) { \
- (port)->FIO_MASK = ~((mask) << (offset)); \
- (port)->FIO_PIN = (bits) << (offset); \
- (port)->FIO_MASK = 0; \
-}
+#define pal_lld_writegroup(port, mask, offset, bits) \
+ ((port)->FIO_MASK = ~((mask) << (offset)), \
+ (port)->FIO_PIN = (bits) << (offset), \
+ (port)->FIO_MASK = 0)
/**
* @brief Pads group mode setup.
@@ -235,9 +235,7 @@ typedef FIO * ioportid_t;
*
* @notapi
*/
-#define pal_lld_lpc214x_set_direction(port, dir) { \
- (port)->FIO_DIR = (dir); \
-}
+#define pal_lld_lpc214x_set_direction(port, dir) ((port)->FIO_DIR = (dir))
extern const PALConfig pal_default_config;
diff --git a/os/hal/platforms/LPC214x/platform.dox b/os/hal/platforms/LPC214x/platform.dox
index b07cce8c6..cfd9a4078 100644
--- a/os/hal/platforms/LPC214x/platform.dox
+++ b/os/hal/platforms/LPC214x/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -43,7 +44,7 @@
*/
/**
- * @defgroup LPC214x_PAL LPC214x FIO Support
+ * @defgroup LPC214x_PAL LPC214x PAL Support
* @details The LPC214x PAL driver uses the FIO peripherals.
*
* @section lpc214x_pal_1 Supported HW resources
@@ -74,26 +75,7 @@
*/
/**
- * @defgroup LPC214x_SPI LPC214x SSP Support
- * @details The SPI driver supports the LPC214x SSP peripheral in an interrupt
- * driven implementation.
- * @note Being the SPI a fast peripheral, much care must be taken to
- * not saturate the CPU bandwidth with an excessive IRQ rate. The
- * maximum transfer bit rate is likely limited by the IRQ
- * handling.
- *
- * @section lpc214x_spi_1 Supported HW resources
- * - SSP (SPI0).
- * .
- * @section lpc214x_spi_2 LPC214x SPI driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Programmable interrupt priority level.
- * .
- * @ingroup LPC214x
- */
-
-/**
- * @defgroup LPC214x_SERIAL LPC214x UART Support (buffered)
+ * @defgroup LPC214x_SERIAL LPC214x Serial Support
* @details The LPC214x Serial driver uses the UART peripherals in a
* buffered, interrupt driven, implementation. The serial driver
* also takes advantage of the LPC214x UARTs deep hardware buffers.
@@ -113,6 +95,25 @@
*/
/**
+ * @defgroup LPC214x_SPI LPC214x SPI Support
+ * @details The SPI driver supports the LPC214x SSP peripheral in an interrupt
+ * driven implementation.
+ * @note Being the SPI a fast peripheral, much care must be taken to
+ * not saturate the CPU bandwidth with an excessive IRQ rate. The
+ * maximum transfer bit rate is likely limited by the IRQ
+ * handling.
+ *
+ * @section lpc214x_spi_1 Supported HW resources
+ * - SSP (SPI0).
+ * .
+ * @section lpc214x_spi_2 LPC214x SPI driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Programmable interrupt priority level.
+ * .
+ * @ingroup LPC214x
+ */
+
+/**
* @defgroup LPC214x_VIC LPC214x VIC Support
* @details This VIC helper driver is used by the other drivers in order to
* access the shared VIC resources in a consistent way.
diff --git a/os/hal/platforms/LPC214x/serial_lld.c b/os/hal/platforms/LPC214x/serial_lld.c
index cc6280d79..91c6d560a 100644
--- a/os/hal/platforms/LPC214x/serial_lld.c
+++ b/os/hal/platforms/LPC214x/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/serial_lld.h b/os/hal/platforms/LPC214x/serial_lld.h
index 4dac88f20..b51fb395d 100644
--- a/os/hal/platforms/LPC214x/serial_lld.h
+++ b/os/hal/platforms/LPC214x/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/spi_lld.c b/os/hal/platforms/LPC214x/spi_lld.c
index f920ecf87..e59087b25 100644
--- a/os/hal/platforms/LPC214x/spi_lld.c
+++ b/os/hal/platforms/LPC214x/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -53,21 +54,21 @@ SPIDriver SPID1;
* @param[in] spip pointer to the @p SPIDriver object
*/
static void ssp_fifo_preload(SPIDriver *spip) {
- SSP *ssp = spip->spd_ssp;
- uint32_t n = spip->spd_txcnt > LPC214x_SSP_FIFO_DEPTH ?
- LPC214x_SSP_FIFO_DEPTH : spip->spd_txcnt;
+ SSP *ssp = spip->ssp;
+ uint32_t n = spip->txcnt > LPC214x_SSP_FIFO_DEPTH ?
+ LPC214x_SSP_FIFO_DEPTH : spip->txcnt;
while(((ssp->SSP_SR & SR_TNF) != 0) && (n > 0)) {
- if (spip->spd_txptr != NULL) {
+ if (spip->txptr != NULL) {
if ((ssp->SSP_CR0 & CR0_DSSMASK) > CR0_DSS8BIT)
- ssp->SSP_DR = *(uint16_t *)spip->spd_txptr++;
+ ssp->SSP_DR = *(uint16_t *)spip->txptr++;
else
- ssp->SSP_DR = *(uint8_t *)spip->spd_txptr++;
+ ssp->SSP_DR = *(uint8_t *)spip->txptr++;
}
else
ssp->SSP_DR = 0xFFFFFFFF;
n--;
- spip->spd_txcnt--;
+ spip->txcnt--;
}
}
@@ -80,7 +81,7 @@ __attribute__((noinline))
* @param[in] spip pointer to the @p SPIDriver object
*/
static void serve_interrupt(SPIDriver *spip) {
- SSP *ssp = spip->spd_ssp;
+ SSP *ssp = spip->ssp;
if ((ssp->SSP_MIS & MIS_ROR) != 0) {
/* The overflow condition should never happen because priority is given
@@ -89,16 +90,16 @@ static void serve_interrupt(SPIDriver *spip) {
}
ssp->SSP_ICR = ICR_RT | ICR_ROR;
while ((ssp->SSP_SR & SR_RNE) != 0) {
- if (spip->spd_rxptr != NULL) {
+ if (spip->rxptr != NULL) {
if ((ssp->SSP_CR0 & CR0_DSSMASK) > CR0_DSS8BIT)
- *(uint16_t *)spip->spd_rxptr++ = ssp->SSP_DR;
+ *(uint16_t *)spip->rxptr++ = ssp->SSP_DR;
else
- *(uint8_t *)spip->spd_rxptr++ = ssp->SSP_DR;
+ *(uint8_t *)spip->rxptr++ = ssp->SSP_DR;
}
else
(void)ssp->SSP_DR;
- if (--spip->spd_rxcnt == 0) {
- chDbgAssert(spip->spd_txcnt == 0,
+ if (--spip->rxcnt == 0) {
+ chDbgAssert(spip->txcnt == 0,
"spi_serve_interrupt(), #1", "counter out of synch");
/* Stops the IRQ sources.*/
ssp->SSP_IMSC = 0;
@@ -109,7 +110,7 @@ static void serve_interrupt(SPIDriver *spip) {
}
}
ssp_fifo_preload(spip);
- if (spip->spd_txcnt == 0)
+ if (spip->txcnt == 0)
ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_RX;
}
@@ -147,7 +148,7 @@ void spi_lld_init(void) {
#if LPC214x_SPI_USE_SSP
spiObjectInit(&SPID1);
- SPID1.spd_ssp = SSPBase;
+ SPID1.ssp = SSPBase;
SetVICVector(SPI1IrqHandler, LPC214x_SPI_SSP_IRQ_PRIORITY, SOURCE_SPI1);
#endif
}
@@ -161,7 +162,7 @@ void spi_lld_init(void) {
*/
void spi_lld_start(SPIDriver *spip) {
- if (spip->spd_state == SPI_STOP) {
+ if (spip->state == SPI_STOP) {
/* Clock activation.*/
#if LPC214x_SPI_USE_SSP
if (&SPID1 == spip) {
@@ -171,14 +172,14 @@ void spi_lld_start(SPIDriver *spip) {
#endif
}
/* Configuration.*/
- spip->spd_ssp->SSP_CR1 = 0;
+ spip->ssp->SSP_CR1 = 0;
/* Emptying the receive FIFO, it happens to not be empty while debugging.*/
- while (spip->spd_ssp->SSP_SR & SR_RNE)
- (void) spip->spd_ssp->SSP_DR;
- spip->spd_ssp->SSP_ICR = ICR_RT | ICR_ROR;
- spip->spd_ssp->SSP_CR0 = spip->spd_config->spc_cr0;
- spip->spd_ssp->SSP_CPSR = spip->spd_config->spc_cpsr;
- spip->spd_ssp->SSP_CR1 = CR1_SSE;
+ while (spip->ssp->SSP_SR & SR_RNE)
+ (void) spip->ssp->SSP_DR;
+ spip->ssp->SSP_ICR = ICR_RT | ICR_ROR;
+ spip->ssp->SSP_CR0 = spip->config->cr0;
+ spip->ssp->SSP_CPSR = spip->config->cpsr;
+ spip->ssp->SSP_CR1 = CR1_SSE;
}
/**
@@ -190,10 +191,10 @@ void spi_lld_start(SPIDriver *spip) {
*/
void spi_lld_stop(SPIDriver *spip) {
- if (spip->spd_state != SPI_STOP) {
- spip->spd_ssp->SSP_CR1 = 0;
- spip->spd_ssp->SSP_CR0 = 0;
- spip->spd_ssp->SSP_CPSR = 0;
+ if (spip->state != SPI_STOP) {
+ spip->ssp->SSP_CR1 = 0;
+ spip->ssp->SSP_CR0 = 0;
+ spip->ssp->SSP_CPSR = 0;
#if LPC214x_SPI_USE_SSP
if (&SPID1 == spip) {
PCONP = (PCONP & PCALL) & ~PCSPI1;
@@ -212,7 +213,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
- palClearPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -225,7 +226,7 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
- palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -241,11 +242,11 @@ void spi_lld_unselect(SPIDriver *spip) {
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -266,11 +267,11 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -288,11 +289,11 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -310,11 +311,11 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
- spip->spd_ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+ spip->ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
@@ -331,10 +332,10 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
*/
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
- spip->spd_ssp->SSP_DR = (uint32_t)frame;
- while ((spip->spd_ssp->SSP_SR & SR_RNE) == 0)
+ spip->ssp->SSP_DR = (uint32_t)frame;
+ while ((spip->ssp->SSP_SR & SR_RNE) == 0)
;
- return (uint16_t)spip->spd_ssp->SSP_DR;
+ return (uint16_t)spip->ssp->SSP_DR;
}
#endif /* HAL_USE_SPI */
diff --git a/os/hal/platforms/LPC214x/spi_lld.h b/os/hal/platforms/LPC214x/spi_lld.h
index 0e9a3e782..e6a76bd8f 100644
--- a/os/hal/platforms/LPC214x/spi_lld.h
+++ b/os/hal/platforms/LPC214x/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -35,7 +36,7 @@
/*===========================================================================*/
/**
- * @brief Hardware FIFO depth.
+ * @brief Hardware FIFO depth.
*/
#define LPC214x_SSP_FIFO_DEPTH 8
@@ -99,24 +100,24 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
- ioportid_t spc_ssport;
+ ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
- uint16_t spc_sspad;
+ uint16_t sspad;
/**
* @brief SSP CR0 initialization data.
*/
- uint16_t spc_cr0;
+ uint16_t cr0;
/**
* @brief SSP CPSR initialization data.
*/
- uint32_t spc_cpsr;
+ uint32_t cpsr;
} SPIConfig;
/**
@@ -126,25 +127,25 @@ struct SPIDriver {
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
@@ -154,23 +155,23 @@ struct SPIDriver {
/**
* @brief Pointer to the SSP registers block.
*/
- SSP *spd_ssp;
+ SSP *ssp;
/**
- * @brief Number of bytes yet to be received.
+ * @brief Number of bytes yet to be received.
*/
- uint32_t spd_rxcnt;
+ uint32_t rxcnt;
/**
* @brief Receive pointer or @p NULL.
*/
- void *spd_rxptr;
+ void *rxptr;
/**
* @brief Number of bytes yet to be transmitted.
*/
- uint32_t spd_txcnt;
+ uint32_t txcnt;
/**
* @brief Transmit pointer or @p NULL.
*/
- const void *spd_txptr;
+ const void *txptr;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/LPC214x/vic.c b/os/hal/platforms/LPC214x/vic.c
index f1b75aa80..d613f3af7 100644
--- a/os/hal/platforms/LPC214x/vic.c
+++ b/os/hal/platforms/LPC214x/vic.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/LPC214x/vic.h b/os/hal/platforms/LPC214x/vic.h
index c0fd3ea3e..a6184ce97 100644
--- a/os/hal/platforms/LPC214x/vic.h
+++ b/os/hal/platforms/LPC214x/vic.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/MSP430/hal_lld.c b/os/hal/platforms/MSP430/hal_lld.c
index 0de477f43..0d3de0632 100644
--- a/os/hal/platforms/MSP430/hal_lld.c
+++ b/os/hal/platforms/MSP430/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/MSP430/hal_lld.h b/os/hal/platforms/MSP430/hal_lld.h
index 8f9ae59af..c2c23342f 100644
--- a/os/hal/platforms/MSP430/hal_lld.h
+++ b/os/hal/platforms/MSP430/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/MSP430/pal_lld.c b/os/hal/platforms/MSP430/pal_lld.c
index 5ea89254e..073a6af93 100644
--- a/os/hal/platforms/MSP430/pal_lld.c
+++ b/os/hal/platforms/MSP430/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/MSP430/pal_lld.h b/os/hal/platforms/MSP430/pal_lld.h
index ce5d47dce..31ee669a0 100644
--- a/os/hal/platforms/MSP430/pal_lld.h
+++ b/os/hal/platforms/MSP430/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -254,9 +255,7 @@ typedef msp430_ioport_t *ioportid_t;
*
* @notapi
*/
-#define pal_lld_writeport(port, bits) { \
- (port)->iop_common.out.reg_p = (bits); \
-}
+#define pal_lld_writeport(port, bits) ((port)->iop_common.out.reg_p = (bits))
/**
* @brief Pads group mode setup.
diff --git a/os/hal/platforms/MSP430/platform.dox b/os/hal/platforms/MSP430/platform.dox
index ec6bbd535..e326b90ef 100644
--- a/os/hal/platforms/MSP430/platform.dox
+++ b/os/hal/platforms/MSP430/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -41,7 +42,7 @@
*/
/**
- * @defgroup MSP430_PAL MSP430 PORT Support
+ * @defgroup MSP430_PAL MSP430 PAL Support
* @details The MSP430 PAL driver uses the PORT peripherals.
*
* @section msp430_pal_1 Supported HW resources
@@ -79,7 +80,7 @@
*/
/**
- * @defgroup MSP430_SERIAL MSP430 USART Support (buffered)
+ * @defgroup MSP430_SERIAL MSP430 Serial Support
* @details The MSP430 Serial driver uses the USART peripherals in a
* buffered, interrupt driven, implementation.
*
diff --git a/os/hal/platforms/MSP430/serial_lld.c b/os/hal/platforms/MSP430/serial_lld.c
index c6000d7a8..04a58a580 100644
--- a/os/hal/platforms/MSP430/serial_lld.c
+++ b/os/hal/platforms/MSP430/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -174,7 +175,7 @@ static void usart1_deinit(void) {
/**
* @brief USART0 TX interrupt handler.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(USART0TX_VECTOR) {
msg_t b;
diff --git a/os/hal/platforms/MSP430/serial_lld.h b/os/hal/platforms/MSP430/serial_lld.h
index 42788abcf..9f965b2cd 100644
--- a/os/hal/platforms/MSP430/serial_lld.h
+++ b/os/hal/platforms/MSP430/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/console.c b/os/hal/platforms/Posix/console.c
index 737cf92bf..4f29b7900 100644
--- a/os/hal/platforms/Posix/console.c
+++ b/os/hal/platforms/Posix/console.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/console.h b/os/hal/platforms/Posix/console.h
index 3a30e6295..b803a5de7 100644
--- a/os/hal/platforms/Posix/console.h
+++ b/os/hal/platforms/Posix/console.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/hal_lld.c b/os/hal/platforms/Posix/hal_lld.c
index 6f1433586..1eb0af355 100644
--- a/os/hal/platforms/Posix/hal_lld.c
+++ b/os/hal/platforms/Posix/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/hal_lld.h b/os/hal/platforms/Posix/hal_lld.h
index 69892ce6f..192f7fefc 100644
--- a/os/hal/platforms/Posix/hal_lld.h
+++ b/os/hal/platforms/Posix/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/pal_lld.c b/os/hal/platforms/Posix/pal_lld.c
index 3dc664878..c3d88a8fb 100644
--- a/os/hal/platforms/Posix/pal_lld.c
+++ b/os/hal/platforms/Posix/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/pal_lld.h b/os/hal/platforms/Posix/pal_lld.h
index 3612e4498..1984c06f0 100644
--- a/os/hal/platforms/Posix/pal_lld.h
+++ b/os/hal/platforms/Posix/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -128,10 +129,9 @@ typedef sim_vio_port_t *ioportid_t;
*
* @param[in] config architecture-dependent ports configuration
*/
-#define pal_lld_init(config) { \
- vio_port_1 = (config)->VP1Data; \
- vio_port_2 = (config)->VP2Data; \
-}
+#define pal_lld_init(config) \
+ (vio_port_1 = (config)->VP1Data, \
+ vio_port_2 = (config)->VP2Data)
/**
* @brief Reads the physical I/O port states.
@@ -177,7 +177,7 @@ typedef sim_vio_port_t *ioportid_t;
* @param[in] mask group mask
* @param[in] mode group mode
*/
-#define pal_lld_setgroupmode(port, mask, mode) \
+#define pal_lld_setgroupmode(port, mask, mode) \
_pal_lld_setgroupmode(port, mask, mode)
#if !defined(__DOXYGEN__)
diff --git a/os/hal/platforms/Posix/serial_lld.c b/os/hal/platforms/Posix/serial_lld.c
index 128f3e2fb..31be73825 100644
--- a/os/hal/platforms/Posix/serial_lld.c
+++ b/os/hal/platforms/Posix/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Posix/serial_lld.h b/os/hal/platforms/Posix/serial_lld.h
index 282b68314..c0a28b819 100644
--- a/os/hal/platforms/Posix/serial_lld.h
+++ b/os/hal/platforms/Posix/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/SPC56x/hal_lld.c b/os/hal/platforms/SPC56x/hal_lld.c
index 4d4a10c41..afb93b73d 100644
--- a/os/hal/platforms/SPC56x/hal_lld.c
+++ b/os/hal/platforms/SPC56x/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/SPC56x/hal_lld.h b/os/hal/platforms/SPC56x/hal_lld.h
index c61089a38..48b12b19d 100644
--- a/os/hal/platforms/SPC56x/hal_lld.h
+++ b/os/hal/platforms/SPC56x/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -112,7 +113,7 @@
* @note The effective divider factor is this value plus one.
*/
#if !defined(SPC563_CLK_PREDIV) || defined(__DOXYGEN__)
-#define SPC563_CLK_PREDIV 0
+#define SPC563_CLK_PREDIV 2
#endif
/**
@@ -120,7 +121,7 @@
* @note Must be in range 32...96.
*/
#if !defined(SPC563_CLK_MFD) || defined(__DOXYGEN__)
-#define SPC563_CLK_MFD 40
+#define SPC563_CLK_MFD 80
#endif
/**
diff --git a/os/hal/platforms/SPC56x/platform.dox b/os/hal/platforms/SPC56x/platform.dox
index 3308731e9..18e4eaeb9 100644
--- a/os/hal/platforms/SPC56x/platform.dox
+++ b/os/hal/platforms/SPC56x/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -49,7 +50,7 @@
*/
/**
- * @defgroup SPC563_SERIAL SPC563Mx ESCI Support (buffered)
+ * @defgroup SPC563_SERIAL SPC563Mx Serial Support
* @details The SPC563Mx/MPC563xM Serial driver uses the ESCI peripherals
* in a buffered, interrupt driven, implementation.
*
diff --git a/os/hal/platforms/SPC56x/serial_lld.c b/os/hal/platforms/SPC56x/serial_lld.c
index afb23086a..fa31a211e 100644
--- a/os/hal/platforms/SPC56x/serial_lld.c
+++ b/os/hal/platforms/SPC56x/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/SPC56x/serial_lld.h b/os/hal/platforms/SPC56x/serial_lld.h
index 510e3298e..9d4c1bead 100644
--- a/os/hal/platforms/SPC56x/serial_lld.h
+++ b/os/hal/platforms/SPC56x/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/SPC56x/typedefs.h b/os/hal/platforms/SPC56x/typedefs.h
index b9611bf2c..1ee9e1f10 100644
--- a/os/hal/platforms/SPC56x/typedefs.h
+++ b/os/hal/platforms/SPC56x/typedefs.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM32/adc_lld.c b/os/hal/platforms/STM32/adc_lld.c
index 91fd8a6e8..8a8027e55 100644
--- a/os/hal/platforms/STM32/adc_lld.c
+++ b/os/hal/platforms/STM32/adc_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -47,39 +48,35 @@ ADCDriver ADCD1;
/* Driver local functions. */
/*===========================================================================*/
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
/**
- * @brief ADC1 DMA interrupt handler (channel 1).
+ * @brief Shared ADC DMA ISR service routine.
*
- * @isr
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
- uint32_t isr;
+static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
- CH_IRQ_PROLOGUE();
-
- isr = STM32_DMA1->ISR;
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1);
- if ((isr & DMA_ISR_TEIF1) != 0) {
- /* DMA error processing.*/
- STM32_ADC1_DMA_ERROR_HOOK();
+ /* DMA errors handling.*/
+#if defined(STM32_ADC_DMA_ERROR_HOOK)
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_ADC_DMA_ERROR_HOOK(spip);
}
- if ((isr & DMA_ISR_HTIF1) != 0) {
+#else
+ (void)flags;
+#endif
+ if ((flags & DMA_ISR_HTIF1) != 0) {
/* Half transfer processing.*/
- _adc_isr_half_code(&ADCD1);
+ _adc_isr_half_code(adcp);
}
- if ((isr & DMA_ISR_TCIF1) != 0) {
+ if ((flags & DMA_ISR_TCIF1) != 0) {
/* Transfer complete processing.*/
- _adc_isr_full_code(&ADCD1);
+ _adc_isr_full_code(adcp);
}
-
- CH_IRQ_EPILOGUE();
}
-#endif
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
@@ -93,15 +90,11 @@ CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
void adc_lld_init(void) {
#if STM32_ADC_USE_ADC1
- /* ADC reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB2RSTR = RCC_APB2RSTR_ADC1RST;
- RCC->APB2RSTR = 0;
-
/* Driver initialization.*/
adcObjectInit(&ADCD1);
- ADCD1.ad_adc = ADC1;
- ADCD1.ad_dmachp = STM32_DMA1_CH1;
- ADCD1.ad_dmaccr = (STM32_ADC_ADC1_DMA_PRIORITY << 12) |
+ ADCD1.adc = ADC1;
+ ADCD1.dmachp = STM32_DMA1_CH1;
+ ADCD1.dmaccr = (STM32_ADC_ADC1_DMA_PRIORITY << 12) |
DMA_CCR1_EN | DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0 |
DMA_CCR1_MINC | DMA_CCR1_TCIE | DMA_CCR1_TEIE;
@@ -136,21 +129,22 @@ void adc_lld_init(void) {
void adc_lld_start(ADCDriver *adcp) {
/* If in stopped state then enables the ADC and DMA clocks.*/
- if (adcp->ad_state == ADC_STOP) {
+ if (adcp->state == ADC_STOP) {
#if STM32_ADC_USE_ADC1
if (&ADCD1 == adcp) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_1,
+ (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp);
NVICEnableVector(DMA1_Channel1_IRQn,
CORTEX_PRIORITY_MASK(STM32_ADC_ADC1_IRQ_PRIORITY));
- dmaChannelSetPeripheral(adcp->ad_dmachp, &ADC1->DR);
+ dmaChannelSetPeripheral(adcp->dmachp, &ADC1->DR);
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
}
#endif
/* ADC setup, the calibration procedure has already been performed
during initialization.*/
- adcp->ad_adc->CR1 = ADC_CR1_SCAN;
- adcp->ad_adc->CR2 = 0;
+ adcp->adc->CR1 = ADC_CR1_SCAN;
+ adcp->adc->CR2 = 0;
}
}
@@ -164,13 +158,13 @@ void adc_lld_start(ADCDriver *adcp) {
void adc_lld_stop(ADCDriver *adcp) {
/* If in ready state then disables the ADC clock.*/
- if (adcp->ad_state == ADC_READY) {
+ if (adcp->state == ADC_READY) {
#if STM32_ADC_USE_ADC1
if (&ADCD1 == adcp) {
ADC1->CR1 = 0;
ADC1->CR2 = 0;
NVICDisableVector(DMA1_Channel1_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_1);
RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN;
}
#endif
@@ -186,34 +180,34 @@ void adc_lld_stop(ADCDriver *adcp) {
*/
void adc_lld_start_conversion(ADCDriver *adcp) {
uint32_t ccr, n;
- const ADCConversionGroup *grpp = adcp->ad_grpp;
+ const ADCConversionGroup *grpp = adcp->grpp;
/* DMA setup.*/
- ccr = adcp->ad_dmaccr;
- if (grpp->acg_circular)
+ ccr = adcp->dmaccr;
+ if (grpp->circular)
ccr |= DMA_CCR1_CIRC;
- if (adcp->ad_depth > 1) {
+ if (adcp->depth > 1) {
/* If the buffer depth is greater than one then the half transfer interrupt
interrupt is enabled in order to allows streaming processing.*/
ccr |= DMA_CCR1_HTIE;
- n = (uint32_t)grpp->acg_num_channels * (uint32_t)adcp->ad_depth;
+ n = (uint32_t)grpp->num_channels * (uint32_t)adcp->depth;
}
else
- n = (uint32_t)grpp->acg_num_channels;
- dmaChannelSetup(adcp->ad_dmachp, n, adcp->ad_samples, ccr);
+ n = (uint32_t)grpp->num_channels;
+ dmaChannelSetup(adcp->dmachp, n, adcp->samples, ccr);
/* ADC setup.*/
- adcp->ad_adc->CR1 = grpp->acg_cr1 | ADC_CR1_SCAN;
- adcp->ad_adc->CR2 = grpp->acg_cr2 | ADC_CR2_DMA |
+ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN;
+ adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA |
ADC_CR2_CONT | ADC_CR2_ADON;
- adcp->ad_adc->SMPR1 = grpp->acg_smpr1;
- adcp->ad_adc->SMPR2 = grpp->acg_smpr2;
- adcp->ad_adc->SQR1 = grpp->acg_sqr1;
- adcp->ad_adc->SQR2 = grpp->acg_sqr2;
- adcp->ad_adc->SQR3 = grpp->acg_sqr3;
+ adcp->adc->SMPR1 = grpp->smpr1;
+ adcp->adc->SMPR2 = grpp->smpr2;
+ adcp->adc->SQR1 = grpp->sqr1;
+ adcp->adc->SQR2 = grpp->sqr2;
+ adcp->adc->SQR3 = grpp->sqr3;
/* ADC start by writing ADC_CR2_ADON a second time.*/
- adcp->ad_adc->CR2 = grpp->acg_cr2 | ADC_CR2_DMA |
+ adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA |
ADC_CR2_CONT | ADC_CR2_ADON;
}
@@ -226,8 +220,8 @@ void adc_lld_start_conversion(ADCDriver *adcp) {
*/
void adc_lld_stop_conversion(ADCDriver *adcp) {
- dmaChannelDisable(adcp->ad_dmachp);
- adcp->ad_adc->CR2 = 0;
+ dmaChannelDisable(adcp->dmachp);
+ adcp->adc->CR2 = 0;
}
#endif /* HAL_USE_ADC */
diff --git a/os/hal/platforms/STM32/adc_lld.h b/os/hal/platforms/STM32/adc_lld.h
index 876560fca..ce93e60ed 100644
--- a/os/hal/platforms/STM32/adc_lld.h
+++ b/os/hal/platforms/STM32/adc_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -82,7 +83,7 @@
* @brief ADC1 DMA priority (0..3|lowest..highest).
*/
#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_PRIORITY 3
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
#endif
/**
@@ -93,12 +94,12 @@
#endif
/**
- * @brief ADC1 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
+ * @brief ADC DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
*/
-#if !defined(STM32_ADC1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#if !defined(STM32_ADC_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
#endif
/*===========================================================================*/
@@ -113,6 +114,10 @@
#error "ADC driver activated but no ADC peripheral assigned"
#endif
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -154,56 +159,56 @@ typedef struct {
/**
* @brief Enables the circular buffer mode for the group.
*/
- bool_t acg_circular;
+ bool_t circular;
/**
* @brief Number of the analog channels belonging to the conversion group.
*/
- adc_channels_num_t acg_num_channels;
+ adc_channels_num_t num_channels;
/**
* @brief Callback function associated to the group or @p NULL.
*/
- adccallback_t acg_endcb;
+ adccallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief ADC CR1 register initialization data.
* @note All the required bits must be defined into this field except
* @p ADC_CR1_SCAN that is enforced inside the driver.
*/
- uint32_t acg_cr1;
+ uint32_t cr1;
/**
* @brief ADC CR2 register initialization data.
* @note All the required bits must be defined into this field except
* @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are
* enforced inside the driver.
*/
- uint32_t acg_cr2;
+ uint32_t cr2;
/**
* @brief ADC SMPR1 register initialization data.
* @details In this field must be specified the sample times for channels
* 10...17.
*/
- uint32_t acg_smpr1;
+ uint32_t smpr1;
/**
* @brief ADC SMPR2 register initialization data.
* @details In this field must be specified the sample times for channels
* 0...9.
*/
- uint32_t acg_smpr2;
+ uint32_t smpr2;
/**
* @brief ADC SQR1 register initialization data.
* @details Conversion group sequence 13...16 + sequence length.
*/
- uint32_t acg_sqr1;
+ uint32_t sqr1;
/**
* @brief ADC SQR2 register initialization data.
* @details Conversion group sequence 7...12.
*/
- uint32_t acg_sqr2;
+ uint32_t sqr2;
/**
* @brief ADC SQR3 register initialization data.
* @details Conversion group sequence 0...6.
*/
- uint32_t acg_sqr3;
+ uint32_t sqr3;
} ADCConversionGroup;
/**
@@ -221,37 +226,37 @@ struct ADCDriver {
/**
* @brief Driver state.
*/
- adcstate_t ad_state;
+ adcstate_t state;
/**
* @brief Current configuration data.
*/
- const ADCConfig *ad_config;
+ const ADCConfig *config;
/**
* @brief Current samples buffer pointer or @p NULL.
*/
- adcsample_t *ad_samples;
+ adcsample_t *samples;
/**
* @brief Current samples buffer depth or @p 0.
*/
- size_t ad_depth;
+ size_t depth;
/**
* @brief Current conversion group pointer or @p NULL.
*/
- const ADCConversionGroup *ad_grpp;
+ const ADCConversionGroup *grpp;
#if ADC_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *ad_thread;
+ Thread *thread;
#endif
#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the peripheral.
*/
- Mutex ad_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore ad_semaphore;
+ Semaphore semaphore;
#endif
#endif /* ADC_USE_MUTUAL_EXCLUSION */
#if defined(ADC_DRIVER_EXT_FIELDS)
@@ -261,15 +266,15 @@ struct ADCDriver {
/**
* @brief Pointer to the ADCx registers block.
*/
- ADC_TypeDef *ad_adc;
+ ADC_TypeDef *adc;
/**
* @brief Pointer to the DMA registers block.
*/
- stm32_dma_channel_t *ad_dmachp;
+ stm32_dma_channel_t *dmachp;
/**
* @brief DMA CCR register bit mask.
*/
- uint32_t ad_dmaccr;
+ uint32_t dmaccr;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/can_lld.c b/os/hal/platforms/STM32/can_lld.c
index 24a944c0f..e180a87cb 100644
--- a/os/hal/platforms/STM32/can_lld.c
+++ b/os/hal/platforms/STM32/can_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -63,9 +64,9 @@ CH_IRQ_HANDLER(CAN1_TX_IRQHandler) {
/* No more events until a message is transmitted.*/
CAN1->TSR = CAN_TSR_RQCP0 | CAN_TSR_RQCP1 | CAN_TSR_RQCP2;
chSysLockFromIsr();
- while (chSemGetCounterI(&CAND1.cd_txsem) < 0)
- chSemSignalI(&CAND1.cd_txsem);
- chEvtBroadcastI(&CAND1.cd_txempty_event);
+ while (chSemGetCounterI(&CAND1.txsem) < 0)
+ chSemSignalI(&CAND1.txsem);
+ chEvtBroadcastI(&CAND1.txempty_event);
chSysUnlockFromIsr();
CH_IRQ_EPILOGUE();
@@ -86,9 +87,9 @@ CH_IRQ_HANDLER(CAN1_RX0_IRQHandler) {
/* No more receive events until the queue 0 has been emptied.*/
CAN1->IER &= ~CAN_IER_FMPIE0;
chSysLockFromIsr();
- while (chSemGetCounterI(&CAND1.cd_rxsem) < 0)
- chSemSignalI(&CAND1.cd_rxsem);
- chEvtBroadcastI(&CAND1.cd_rxfull_event);
+ while (chSemGetCounterI(&CAND1.rxsem) < 0)
+ chSemSignalI(&CAND1.rxsem);
+ chEvtBroadcastI(&CAND1.rxfull_event);
chSysUnlockFromIsr();
}
if ((rf0r & CAN_RF0R_FOVR0) > 0) {
@@ -96,7 +97,7 @@ CH_IRQ_HANDLER(CAN1_RX0_IRQHandler) {
CAN1->RF0R = CAN_RF0R_FOVR0;
canAddFlagsI(&CAND1, CAN_OVERFLOW_ERROR);
chSysLockFromIsr();
- chEvtBroadcastI(&CAND1.cd_error_event);
+ chEvtBroadcastI(&CAND1.error_event);
chSysUnlockFromIsr();
}
@@ -132,7 +133,7 @@ CH_IRQ_HANDLER(CAN1_SCE_IRQHandler) {
/* Wakeup event.*/
if (msr & CAN_MSR_WKUI) {
chSysLockFromIsr();
- chEvtBroadcastI(&CAND1.cd_wakeup_event);
+ chEvtBroadcastI(&CAND1.wakeup_event);
chSysUnlockFromIsr();
}
/* Error event.*/
@@ -146,7 +147,7 @@ CH_IRQ_HANDLER(CAN1_SCE_IRQHandler) {
flags |= CAN_FRAMING_ERROR;
chSysLockFromIsr();
canAddFlagsI(&CAND1, flags | (canstatus_t)(flags < 16));
- chEvtBroadcastI(&CAND1.cd_error_event);
+ chEvtBroadcastI(&CAND1.error_event);
chSysUnlockFromIsr();
}
@@ -165,13 +166,9 @@ CH_IRQ_HANDLER(CAN1_SCE_IRQHandler) {
void can_lld_init(void) {
#if STM32_CAN_USE_CAN1
- /* CAN reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB1RSTR = RCC_APB1RSTR_CAN1RST;
- RCC->APB1RSTR = 0;
-
/* Driver initialization.*/
canObjectInit(&CAND1);
- CAND1.cd_can = CAN1;
+ CAND1.can = CAN1;
#endif
}
@@ -200,37 +197,37 @@ void can_lld_start(CANDriver *canp) {
#endif
/* Entering initialization mode. */
- canp->cd_state = CAN_STARTING;
- canp->cd_can->MCR = CAN_MCR_INRQ;
- while ((canp->cd_can->MSR & CAN_MSR_INAK) == 0)
+ canp->state = CAN_STARTING;
+ canp->can->MCR = CAN_MCR_INRQ;
+ while ((canp->can->MSR & CAN_MSR_INAK) == 0)
chThdSleepS(1);
/* BTR initialization.*/
- canp->cd_can->BTR = canp->cd_config->cc_btr;
+ canp->can->BTR = canp->config->btr;
/* MCR initialization.*/
- canp->cd_can->MCR = canp->cd_config->cc_mcr;
+ canp->can->MCR = canp->config->mcr;
/* Filters initialization.*/
- canp->cd_can->FMR |= CAN_FMR_FINIT;
- if (canp->cd_config->cc_num > 0) {
+ canp->can->FMR |= CAN_FMR_FINIT;
+ if (canp->config->num > 0) {
uint32_t i, fmask;
CAN_FilterRegister_TypeDef *cfp;
- canp->cd_can->FA1R = 0;
- canp->cd_can->FM1R = 0;
- canp->cd_can->FS1R = 0;
- canp->cd_can->FFA1R = 0;
- cfp = canp->cd_can->sFilterRegister;
+ canp->can->FA1R = 0;
+ canp->can->FM1R = 0;
+ canp->can->FS1R = 0;
+ canp->can->FFA1R = 0;
+ cfp = canp->can->sFilterRegister;
fmask = 1;
for (i = 0; i < CAN_MAX_FILTERS; i++) {
- if (i < canp->cd_config->cc_num) {
- if (canp->cd_config->cc_filters[i].cf_mode)
- canp->cd_can->FM1R |= fmask;
- if (canp->cd_config->cc_filters[i].cf_scale)
- canp->cd_can->FS1R |= fmask;
- if (canp->cd_config->cc_filters[i].cf_assignment)
- canp->cd_can->FFA1R |= fmask;
- cfp->FR1 = canp->cd_config->cc_filters[i].cf_register1;
- cfp->FR2 = canp->cd_config->cc_filters[i].cf_register2;
- canp->cd_can->FA1R |= fmask;
+ if (i < canp->config->num) {
+ if (canp->config->filters[i].mode)
+ canp->can->FM1R |= fmask;
+ if (canp->config->filters[i].scale)
+ canp->can->FS1R |= fmask;
+ if (canp->config->filters[i].assignment)
+ canp->can->FFA1R |= fmask;
+ cfp->FR1 = canp->config->filters[i].register1;
+ cfp->FR2 = canp->config->filters[i].register2;
+ canp->can->FA1R |= fmask;
}
else {
cfp->FR1 = 0;
@@ -245,16 +242,16 @@ void can_lld_start(CANDriver *canp) {
}
else {
/* Setup a default filter.*/
- canp->cd_can->sFilterRegister[0].FR1 = 0;
- canp->cd_can->sFilterRegister[0].FR2 = 0;
- canp->cd_can->FM1R = 0;
- canp->cd_can->FFA1R = 0;
- canp->cd_can->FS1R = 1;
- canp->cd_can->FA1R = 1;
+ canp->can->sFilterRegister[0].FR1 = 0;
+ canp->can->sFilterRegister[0].FR2 = 0;
+ canp->can->FM1R = 0;
+ canp->can->FFA1R = 0;
+ canp->can->FS1R = 1;
+ canp->can->FA1R = 1;
}
- canp->cd_can->FMR &= ~CAN_FMR_FINIT;
+ canp->can->FMR &= ~CAN_FMR_FINIT;
/* Interrupt sources initialization.*/
- canp->cd_can->IER = CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 |
+ canp->can->IER = CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 |
CAN_IER_WKUIE | CAN_IER_ERRIE | CAN_IER_LECIE |
CAN_IER_BOFIE | CAN_IER_EPVIE | CAN_IER_EWGIE |
CAN_IER_FOVIE0 | CAN_IER_FOVIE1;
@@ -270,7 +267,7 @@ void can_lld_start(CANDriver *canp) {
void can_lld_stop(CANDriver *canp) {
/* If in ready state then disables the CAN peripheral.*/
- if (canp->cd_state == CAN_READY) {
+ if (canp->state == CAN_READY) {
#if STM32_CAN_USE_CAN1
if (&CAND1 == canp) {
CAN1->MCR = 0x00010002; /* Register reset value. */
@@ -298,7 +295,7 @@ void can_lld_stop(CANDriver *canp) {
*/
bool_t can_lld_can_transmit(CANDriver *canp) {
- return (canp->cd_can->TSR & CAN_TSR_TME) != 0;
+ return (canp->can->TSR & CAN_TSR_TME) != 0;
}
/**
@@ -314,18 +311,18 @@ void can_lld_transmit(CANDriver *canp, const CANTxFrame *ctfp) {
CAN_TxMailBox_TypeDef *tmbp;
/* Pointer to a free transmission mailbox.*/
- tmbp = &canp->cd_can->sTxMailBox[(canp->cd_can->TSR & CAN_TSR_CODE) >> 24];
+ tmbp = &canp->can->sTxMailBox[(canp->can->TSR & CAN_TSR_CODE) >> 24];
/* Preparing the message.*/
- if (ctfp->cf_IDE)
- tir = ((uint32_t)ctfp->cf_EID << 3) | ((uint32_t)ctfp->cf_RTR << 1) |
+ if (ctfp->IDE)
+ tir = ((uint32_t)ctfp->EID << 3) | ((uint32_t)ctfp->RTR << 1) |
CAN_TI0R_IDE;
else
- tir = ((uint32_t)ctfp->cf_SID << 21) | ((uint32_t)ctfp->cf_RTR << 1);
- tmbp->TDTR = ctfp->cf_DLC;
- tmbp->TDLR = ctfp->cf_data32[0];
- tmbp->TDHR = ctfp->cf_data32[1];
- tmbp->TIR = tir | CAN_TI0R_TXRQ;
+ tir = ((uint32_t)ctfp->SID << 21) | ((uint32_t)ctfp->RTR << 1);
+ tmbp->TDTR = ctfp->DLC;
+ tmbp->TDLR = ctfp->data32[0];
+ tmbp->TDHR = ctfp->data32[1];
+ tmbp->TIR = tir | CAN_TI0R_TXRQ;
}
/**
@@ -341,7 +338,7 @@ void can_lld_transmit(CANDriver *canp, const CANTxFrame *ctfp) {
*/
bool_t can_lld_can_receive(CANDriver *canp) {
- return (canp->cd_can->RF0R & CAN_RF0R_FMP0) > 0;
+ return (canp->can->RF0R & CAN_RF0R_FMP0) > 0;
}
/**
@@ -356,27 +353,27 @@ void can_lld_receive(CANDriver *canp, CANRxFrame *crfp) {
uint32_t r;
/* Fetches the message.*/
- r = canp->cd_can->sFIFOMailBox[0].RIR;
- crfp->cf_RTR = (r & CAN_RI0R_RTR) >> 1;
- crfp->cf_IDE = (r & CAN_RI0R_IDE) >> 2;
- if (crfp->cf_IDE)
- crfp->cf_EID = r >> 3;
+ r = canp->can->sFIFOMailBox[0].RIR;
+ crfp->RTR = (r & CAN_RI0R_RTR) >> 1;
+ crfp->IDE = (r & CAN_RI0R_IDE) >> 2;
+ if (crfp->IDE)
+ crfp->EID = r >> 3;
else
- crfp->cf_SID = r >> 21;
- r = canp->cd_can->sFIFOMailBox[0].RDTR;
- crfp->cf_DLC = r & CAN_RDT0R_DLC;
- crfp->cf_FMI = (uint8_t)(r >> 8);
- crfp->cf_TIME = (uint16_t)(r >> 16);
- crfp->cf_data32[0] = canp->cd_can->sFIFOMailBox[0].RDLR;
- crfp->cf_data32[1] = canp->cd_can->sFIFOMailBox[0].RDHR;
+ crfp->SID = r >> 21;
+ r = canp->can->sFIFOMailBox[0].RDTR;
+ crfp->DLC = r & CAN_RDT0R_DLC;
+ crfp->FMI = (uint8_t)(r >> 8);
+ crfp->TIME = (uint16_t)(r >> 16);
+ crfp->data32[0] = canp->can->sFIFOMailBox[0].RDLR;
+ crfp->data32[1] = canp->can->sFIFOMailBox[0].RDHR;
/* Releases the mailbox.*/
- canp->cd_can->RF0R = CAN_RF0R_RFOM0;
+ canp->can->RF0R = CAN_RF0R_RFOM0;
/* If the queue is empty re-enables the interrupt in order to generate
events again.*/
- if ((canp->cd_can->RF0R & CAN_RF0R_FMP0) == 0)
- canp->cd_can->IER |= CAN_IER_FMPIE0;
+ if ((canp->can->RF0R & CAN_RF0R_FMP0) == 0)
+ canp->can->IER |= CAN_IER_FMPIE0;
}
#if CAN_USE_SLEEP_MODE || defined(__DOXYGEN__)
@@ -389,7 +386,7 @@ void can_lld_receive(CANDriver *canp, CANRxFrame *crfp) {
*/
void can_lld_sleep(CANDriver *canp) {
- canp->cd_can->MCR |= CAN_MCR_SLEEP;
+ canp->can->MCR |= CAN_MCR_SLEEP;
}
/**
@@ -401,7 +398,7 @@ void can_lld_sleep(CANDriver *canp) {
*/
void can_lld_wakeup(CANDriver *canp) {
- canp->cd_can->MCR &= ~CAN_MCR_SLEEP;
+ canp->can->MCR &= ~CAN_MCR_SLEEP;
}
#endif /* CAN_USE_SLEEP_MODE */
diff --git a/os/hal/platforms/STM32/can_lld.h b/os/hal/platforms/STM32/can_lld.h
index 0d4c9b615..a9a086e5b 100644
--- a/os/hal/platforms/STM32/can_lld.h
+++ b/os/hal/platforms/STM32/can_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -121,22 +122,22 @@ typedef uint32_t canstatus_t;
*/
typedef struct {
struct {
- uint8_t cf_DLC:4; /**< @brief Data length. */
- uint8_t cf_RTR:1; /**< @brief Frame type. */
- uint8_t cf_IDE:1; /**< @brief Identifier type. */
+ uint8_t DLC:4; /**< @brief Data length. */
+ uint8_t RTR:1; /**< @brief Frame type. */
+ uint8_t IDE:1; /**< @brief Identifier type. */
};
union {
struct {
- uint32_t cf_SID:11; /**< @brief Standard identifier.*/
+ uint32_t SID:11; /**< @brief Standard identifier.*/
};
struct {
- uint32_t cf_EID:29; /**< @brief Extended identifier.*/
+ uint32_t EID:29; /**< @brief Extended identifier.*/
};
};
union {
- uint8_t cf_data8[8]; /**< @brief Frame data. */
- uint16_t cf_data16[4]; /**< @brief Frame data. */
- uint32_t cf_data32[2]; /**< @brief Frame data. */
+ uint8_t data8[8]; /**< @brief Frame data. */
+ uint16_t data16[4]; /**< @brief Frame data. */
+ uint32_t data32[2]; /**< @brief Frame data. */
};
} CANTxFrame;
@@ -147,26 +148,26 @@ typedef struct {
*/
typedef struct {
struct {
- uint8_t cf_FMI; /**< @brief Filter id. */
- uint16_t cf_TIME; /**< @brief Time stamp. */
+ uint8_t FMI; /**< @brief Filter id. */
+ uint16_t TIME; /**< @brief Time stamp. */
};
struct {
- uint8_t cf_DLC:4; /**< @brief Data length. */
- uint8_t cf_RTR:1; /**< @brief Frame type. */
- uint8_t cf_IDE:1; /**< @brief Identifier type. */
+ uint8_t DLC:4; /**< @brief Data length. */
+ uint8_t RTR:1; /**< @brief Frame type. */
+ uint8_t IDE:1; /**< @brief Identifier type. */
};
union {
struct {
- uint32_t cf_SID:11; /**< @brief Standard identifier.*/
+ uint32_t SID:11; /**< @brief Standard identifier.*/
};
struct {
- uint32_t cf_EID:29; /**< @brief Extended identifier.*/
+ uint32_t EID:29; /**< @brief Extended identifier.*/
};
};
union {
- uint8_t cf_data8[8]; /**< @brief Frame data. */
- uint16_t cf_data16[4]; /**< @brief Frame data. */
- uint32_t cf_data32[2]; /**< @brief Frame data. */
+ uint8_t data8[8]; /**< @brief Frame data. */
+ uint16_t data16[4]; /**< @brief Frame data. */
+ uint32_t data32[2]; /**< @brief Frame data. */
};
} CANRxFrame;
@@ -180,27 +181,27 @@ typedef struct {
* @note This bit represent the CAN_FM1R register bit associated to this
* filter (0=mask mode, 1=list mode).
*/
- uint32_t cf_mode:1;
+ uint32_t mode:1;
/**
* @brief Filter sclae.
* @note This bit represent the CAN_FS1R register bit associated to this
* filter (0=16 bits mode, 1=32 bits mode).
*/
- uint32_t cf_scale:1;
+ uint32_t scale:1;
/**
* @brief Filter mode.
* @note This bit represent the CAN_FFA1R register bit associated to this
* filter, must be set to zero in this version of the driver.
*/
- uint32_t cf_assignment:1;
+ uint32_t assignment:1;
/**
* @brief Filter register 1 (identifier).
*/
- uint32_t cf_register1;
+ uint32_t register1;
/**
- * @brief Filter register 2 (mask/identifier depending on cf_mode=0/1).
+ * @brief Filter register 2 (mask/identifier depending on mode=0/1).
*/
- uint32_t cf_register2;
+ uint32_t register2;
} CANFilter;
/**
@@ -212,25 +213,25 @@ typedef struct {
* @note Some bits in this register are enforced by the driver regardless
* their status in this field.
*/
- uint32_t cc_mcr;
+ uint32_t mcr;
/**
* @brief CAN BTR register initialization data.
* @note Some bits in this register are enforced by the driver regardless
* their status in this field.
*/
- uint32_t cc_btr;
+ uint32_t btr;
/**
* @brief Number of elements into the filters array.
* @note By setting this field to zero a default filter is enabled that
* allows all frames, this should be adequate for simple applications.
*/
- uint32_t cc_num;
+ uint32_t num;
/**
* @brief Pointer to an array of @p CANFilter structures.
- * @note This field can be set to @p NULL if the field @p cc_num is set to
+ * @note This field can be set to @p NULL if the field @p num is set to
* zero.
*/
- const CANFilter *cc_filters;
+ const CANFilter *filters;
} CANConfig;
/**
@@ -240,19 +241,19 @@ typedef struct {
/**
* @brief Driver state.
*/
- canstate_t cd_state;
+ canstate_t state;
/**
* @brief Current configuration data.
*/
- const CANConfig *cd_config;
+ const CANConfig *config;
/**
* @brief Transmission queue semaphore.
*/
- Semaphore cd_txsem;
+ Semaphore txsem;
/**
* @brief Receive queue semaphore.
*/
- Semaphore cd_rxsem;
+ Semaphore rxsem;
/**
* @brief One or more frames become available.
* @note After broadcasting this event it will not be broadcasted again
@@ -262,34 +263,34 @@ typedef struct {
* invoking @p chReceive() when listening to this event. This behavior
* minimizes the interrupt served by the system because CAN traffic.
*/
- EventSource cd_rxfull_event;
+ EventSource rxfull_event;
/**
* @brief One or more transmission slots become available.
*/
- EventSource cd_txempty_event;
+ EventSource txempty_event;
/**
* @brief A CAN bus error happened.
*/
- EventSource cd_error_event;
+ EventSource error_event;
/**
* @brief Error flags set when an error event is broadcasted.
*/
- canstatus_t cd_status;
+ canstatus_t status;
#if CAN_USE_SLEEP_MODE || defined (__DOXYGEN__)
/**
* @brief Entering sleep state event.
*/
- EventSource cd_sleep_event;
+ EventSource sleep_event;
/**
* @brief Exiting sleep state event.
*/
- EventSource cd_wakeup_event;
+ EventSource wakeup_event;
#endif /* CAN_USE_SLEEP_MODE */
/* End of the mandatory fields.*/
/**
* @brief Pointer to the CAN registers.
*/
- CAN_TypeDef *cd_can;
+ CAN_TypeDef *can;
} CANDriver;
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/core_cm3.h b/os/hal/platforms/STM32/core_cm3.h
index 5c75ec859..387221bc6 100644
--- a/os/hal/platforms/STM32/core_cm3.h
+++ b/os/hal/platforms/STM32/core_cm3.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM32/gpt_lld.c b/os/hal/platforms/STM32/gpt_lld.c
new file mode 100644
index 000000000..8419cad68
--- /dev/null
+++ b/os/hal/platforms/STM32/gpt_lld.c
@@ -0,0 +1,417 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/gpt_lld.c
+ * @brief STM32 GPT subsystem low level driver source.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/* There are differences in vector names in the ST header for devices
+ including TIM15, TIM16, TIM17.*/
+#if STM32_HAS_TIM15
+#define TIM1_BRK_IRQn TIM1_BRK_TIM15_IRQn
+#endif
+#if STM32_HAS_TIM16
+#define TIM1_UP_IRQn TIM1_UP_TIM16_IRQn
+#endif
+#if STM32_HAS_TIM17
+#define TIM1_TRG_COM_IRQn TIM1_TRG_COM_TIM17_IRQn
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief GPTD1 driver identifier.
+ * @note The driver GPTD1 allocates the complex timer TIM1 when enabled.
+ */
+#if STM32_GPT_USE_TIM1 || defined(__DOXYGEN__)
+GPTDriver GPTD1;
+#endif
+
+/**
+ * @brief GPTD2 driver identifier.
+ * @note The driver GPTD2 allocates the timer TIM2 when enabled.
+ */
+#if STM32_GPT_USE_TIM2 || defined(__DOXYGEN__)
+GPTDriver GPTD2;
+#endif
+
+/**
+ * @brief GPTD3 driver identifier.
+ * @note The driver GPTD3 allocates the timer TIM3 when enabled.
+ */
+#if STM32_GPT_USE_TIM3 || defined(__DOXYGEN__)
+GPTDriver GPTD3;
+#endif
+
+/**
+ * @brief GPTD4 driver identifier.
+ * @note The driver GPTD4 allocates the timer TIM4 when enabled.
+ */
+#if STM32_GPT_USE_TIM4 || defined(__DOXYGEN__)
+GPTDriver GPTD4;
+#endif
+
+/**
+ * @brief GPTD5 driver identifier.
+ * @note The driver GPTD5 allocates the timer TIM5 when enabled.
+ */
+#if STM32_GPT_USE_TIM5 || defined(__DOXYGEN__)
+GPTDriver GPTD5;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Shared IRQ handler.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ */
+static void gpt_lld_serve_interrupt(GPTDriver *gptp) {
+
+ gptp->tim->SR = 0;
+ if (gptp->state == GPT_ONESHOT) {
+ gptp->state = GPT_READY; /* Back in GPT_READY state. */
+ gpt_lld_stop_timer(gptp); /* Timer automatically stopped. */
+ }
+ gptp->config->callback(gptp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_GPT_USE_TIM1
+/**
+ * @brief TIM2 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM1_UP_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD1);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_GPT_USE_TIM1 */
+
+#if STM32_GPT_USE_TIM2
+/**
+ * @brief TIM2 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM2_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD2);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_GPT_USE_TIM2 */
+
+#if STM32_GPT_USE_TIM3
+/**
+ * @brief TIM3 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM3_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD3);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_GPT_USE_TIM3 */
+
+#if STM32_GPT_USE_TIM4
+/**
+ * @brief TIM4 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM4_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD4);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_GPT_USE_TIM4 */
+
+#if STM32_GPT_USE_TIM5
+/**
+ * @brief TIM5 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM5_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD5);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_GPT_USE_TIM5 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level GPT driver initialization.
+ *
+ * @notapi
+ */
+void gpt_lld_init(void) {
+
+#if STM32_GPT_USE_TIM1
+ /* Driver initialization.*/
+ GPTD1.tim = TIM1;
+ gptObjectInit(&GPTD1);
+#endif
+
+#if STM32_GPT_USE_TIM2
+ /* Driver initialization.*/
+ GPTD2.tim = TIM2;
+ gptObjectInit(&GPTD2);
+#endif
+
+#if STM32_GPT_USE_TIM3
+ /* Driver initialization.*/
+ GPTD3.tim = TIM3;
+ gptObjectInit(&GPTD3);
+#endif
+
+#if STM32_GPT_USE_TIM4
+ /* Driver initialization.*/
+ GPTD4.tim = TIM4;
+ gptObjectInit(&GPTD4);
+#endif
+
+#if STM32_GPT_USE_TIM5
+ /* Driver initialization.*/
+ GPTD5.tim = TIM5;
+ gptObjectInit(&GPTD5);
+#endif
+}
+
+/**
+ * @brief Configures and activates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_start(GPTDriver *gptp) {
+ uint16_t psc;
+
+ if (gptp->state == GPT_STOP) {
+ /* Clock activation.*/
+#if STM32_GPT_USE_TIM1
+ if (&GPTD1 == gptp) {
+ RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
+ RCC->APB2RSTR = RCC_APB2RSTR_TIM1RST;
+ RCC->APB2RSTR = 0;
+ NVICEnableVector(TIM1_UP_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_GPT_TIM1_IRQ_PRIORITY));
+ gptp->clock = STM32_TIMCLK2;
+ }
+#endif
+#if STM32_GPT_USE_TIM2
+ if (&GPTD2 == gptp) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM2_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_GPT_TIM2_IRQ_PRIORITY));
+ gptp->clock = STM32_TIMCLK1;
+ }
+#endif
+#if STM32_GPT_USE_TIM3
+ if (&GPTD3 == gptp) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM3RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM3_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_GPT_TIM3_IRQ_PRIORITY));
+ gptp->clock = STM32_TIMCLK1;
+ }
+#endif
+#if STM32_GPT_USE_TIM4
+ if (&GPTD4 == gptp) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM4RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM4_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_GPT_TIM4_IRQ_PRIORITY));
+ gptp->clock = STM32_TIMCLK1;
+ }
+#endif
+
+#if STM32_GPT_USE_TIM5
+ if (&GPTD5 == gptp) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM5RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM5_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_GPT_TIM5_IRQ_PRIORITY));
+ gptp->clock = STM32_TIMCLK1;
+ }
+#endif
+ }
+
+ /* Prescaler value calculation.*/
+ psc = (uint16_t)((gptp->clock / gptp->config->frequency) - 1);
+ chDbgAssert(((uint32_t)(psc + 1) * gptp->config->frequency) == gptp->clock,
+ "gpt_lld_start(), #1", "invalid frequency");
+
+ /* Timer configuration.*/
+ gptp->tim->CR1 = 0; /* Initially stopped. */
+ gptp->tim->CR2 = TIM_CR2_CCDS; /* DMA on UE (if any). */
+ gptp->tim->PSC = psc; /* Prescaler value. */
+ gptp->tim->DIER = 0;
+}
+
+/**
+ * @brief Deactivates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop(GPTDriver *gptp) {
+
+ if (gptp->state == GPT_READY) {
+ gptp->tim->CR1 = 0; /* Timer disabled. */
+ gptp->tim->DIER = 0; /* All IRQs disabled. */
+ gptp->tim->SR = 0; /* Clear eventual pending IRQs. */
+
+#if STM32_GPT_USE_TIM1
+ if (&GPTD1 == gptp) {
+ NVICDisableVector(TIM1_UP_IRQn);
+ RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN;
+ }
+#endif
+#if STM32_GPT_USE_TIM2
+ if (&GPTD2 == gptp) {
+ NVICDisableVector(TIM2_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM2EN;
+ }
+#endif
+#if STM32_GPT_USE_TIM3
+ if (&GPTD3 == gptp) {
+ NVICDisableVector(TIM3_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM3EN;
+ }
+#endif
+#if STM32_GPT_USE_TIM4
+ if (&GPTD4 == gptp) {
+ NVICDisableVector(TIM4_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM4EN;
+ }
+#endif
+#if STM32_GPT_USE_TIM5
+ if (&GPTD5 == gptp) {
+ NVICDisableVector(TIM5_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM5EN;
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tim->ARR = interval - 1; /* Time constant. */
+ gptp->tim->EGR = TIM_EGR_UG; /* Update event. */
+ gptp->tim->SR = 0; /* Clear pending IRQs (if any). */
+ gptp->tim->DIER = TIM_DIER_UIE; /* Update Event IRQ enabled. */
+ gptp->tim->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop_timer(GPTDriver *gptp) {
+
+ gptp->tim->CR1 = 0; /* Initially stopped. */
+ gptp->tim->SR = 0; /* Clear pending IRQs (if any). */
+ gptp->tim->DIER = 0; /* Interrupts disabled. */
+}
+
+/**
+ * @brief Starts the timer in one shot mode and waits for completion.
+ * @details This function specifically polls the timer waiting for completion
+ * in order to not have extra delays caused by interrupt servicing,
+ * this function is only recommended for short delays.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tim->ARR = interval - 1; /* Time constant. */
+ gptp->tim->EGR = TIM_EGR_UG; /* Update event. */
+ gptp->tim->SR = 0; /* Clear pending IRQs (if any). */
+ gptp->tim->CR1 = TIM_CR1_OPM | TIM_CR1_URS | TIM_CR1_CEN;
+ while (!(gptp->tim->SR & TIM_SR_UIF))
+ ;
+}
+
+#endif /* HAL_USE_GPT */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/gpt_lld.h b/os/hal/platforms/STM32/gpt_lld.h
new file mode 100644
index 000000000..cf749077f
--- /dev/null
+++ b/os/hal/platforms/STM32/gpt_lld.h
@@ -0,0 +1,256 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/gpt_lld.h
+ * @brief STM32 GPT subsystem low level driver header.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#ifndef _GPT_LLD_H_
+#define _GPT_LLD_H_
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief GPTD1 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_GPT_USE_TIM1) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM1 TRUE
+#endif
+
+/**
+ * @brief GPTD2 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_GPT_USE_TIM2) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM2 TRUE
+#endif
+
+/**
+ * @brief GPTD3 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD3 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_GPT_USE_TIM3) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM3 TRUE
+#endif
+
+/**
+ * @brief GPTD4 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_GPT_USE_TIM4) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM4 TRUE
+#endif
+
+/**
+ * @brief GPTD5 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD5 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_GPT_USE_TIM5) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM5 TRUE
+#endif
+
+/**
+ * @brief GPTD1 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM1_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD2 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM2_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD3 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM3_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD4 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM4_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD5 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM5_IRQ_PRIORITY 7
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_GPT_USE_TIM1 && !STM32_HAS_TIM1
+#error "TIM1 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM2 && !STM32_HAS_TIM2
+#error "TIM2 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM3 && !STM32_HAS_TIM3
+#error "TIM3 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM4 && !STM32_HAS_TIM4
+#error "TIM4 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM5 && !STM32_HAS_TIM5
+#error "TIM5 not present in the selected device"
+#endif
+
+#if !STM32_GPT_USE_TIM1 && !STM32_GPT_USE_TIM2 && \
+ !STM32_GPT_USE_TIM3 && !STM32_GPT_USE_TIM4 && \
+ !STM32_GPT_USE_TIM5
+#error "GPT driver activated but no TIM peripheral assigned"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT frequency type.
+ */
+typedef uint32_t gptfreq_t;
+
+/**
+ * @brief GPT counter type.
+ */
+typedef uint16_t gptcnt_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ gptfreq_t frequency;
+ /**
+ * @brief Timer callback pointer.
+ * @note This callback is invoked on GPT counter events.
+ */
+ gptcallback_t callback;
+ /* End of the mandatory fields.*/
+} GPTConfig;
+
+/**
+ * @brief Structure representing a GPT driver.
+ */
+struct GPTDriver {
+ /**
+ * @brief Driver state.
+ */
+ gptstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const GPTConfig *config;
+#if defined(GPT_DRIVER_EXT_FIELDS)
+ GPT_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Timer base clock.
+ */
+ uint32_t clock;
+ /**
+ * @brief Pointer to the TIMx registers block.
+ */
+ TIM_TypeDef *tim;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_GPT_USE_TIM1 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD1;
+#endif
+
+#if STM32_GPT_USE_TIM2 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD2;
+#endif
+
+#if STM32_GPT_USE_TIM3 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD3;
+#endif
+
+#if STM32_GPT_USE_TIM4 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD4;
+#endif
+
+#if STM32_GPT_USE_TIM5 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD5;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void gpt_lld_init(void);
+ void gpt_lld_start(GPTDriver *gptp);
+ void gpt_lld_stop(GPTDriver *gptp);
+ void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period);
+ void gpt_lld_stop_timer(GPTDriver *gptp);
+ void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_GPT */
+
+#endif /* _GPT_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/hal_lld.c b/os/hal/platforms/STM32/hal_lld.c
index 8d8322033..9b4feb982 100644
--- a/os/hal/platforms/STM32/hal_lld.c
+++ b/os/hal/platforms/STM32/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -57,6 +58,12 @@
*/
void hal_lld_init(void) {
+ /* Reset of all peripherals.*/
+ RCC->APB1RSTR = 0xFFFFFFFF;
+ RCC->APB2RSTR = 0xFFFFFFFF;
+ RCC->APB1RSTR = 0;
+ RCC->APB2RSTR = 0;
+
/* SysTick initialization using the system clock.*/
SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1;
SysTick->VAL = 0;
@@ -64,7 +71,7 @@ void hal_lld_init(void) {
SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk;
-#if HAL_USE_ADC || HAL_USE_SPI || HAL_USE_UART
+#if defined(STM32_DMA_REQUIRED)
dmaInit();
#endif
}
@@ -76,9 +83,10 @@ void hal_lld_init(void) {
*
* @special
*/
-#if defined(STM32F10X_LD) || defined(STM32F10X_MD) || \
- defined(STM32F10X_HD) || defined(STM32F10X_LD_VL) || \
- defined(STM32F10X_MD_VL) || defined(__DOXYGEN__)
+#if defined(STM32F10X_LD) || defined(STM32F10X_LD_VL) || \
+ defined(STM32F10X_MD) || defined(STM32F10X_MD_VL) || \
+ defined(STM32F10X_HD) || defined(STM32F10X_XL) || \
+ defined(__DOXYGEN__)
/*
* Clocks initialization for the LD, MD and HD sub-families.
*/
@@ -140,43 +148,51 @@ void stm32_clock_init(void) {
*/
void stm32_clock_init(void) {
- /* HSI setup, it enforces the reset situation in order to handle possible
- problems with JTAG probes and re-initializations.*/
+ /* HSI setup.*/
RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */
while (!(RCC->CR & RCC_CR_HSIRDY))
; /* Wait until HSI is stable. */
+ RCC->CFGR = 0;
RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */
- RCC->CFGR = 0; /* CFGR reset value. */
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
; /* Wait until HSI is the source.*/
- RCC->CFGR2 = 0;
- /* HSE setup, it is only performed if the HSE clock is selected as source
- of the system clock (directly or through the PLLs).*/
-#if (STM32_SW == STM32_SW_HSE) || \
- ((STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_PREDIV1))
+ /* HSE setup, it is only performed if the current configuration uses
+ it somehow.*/
+#if STM32_ACTIVATE_PLL2 || \
+ STM32_ACTIVATE_PLL3 || \
+ (STM32_SW == STM32_SW_HSE) || \
+ ((STM32_PREDIV1SRC == STM32_PREDIV1SRC_HSE) && \
+ (STM32_PLLSRC == STM32_PLLSRC_PREDIV1))
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY))
; /* Waits until HSE is stable. */
#endif
- /* PLL2 setup, it is only performed if the PLL2 clock is selected as source
- for the PLL clock else it is left disabled.*/
-#if STM32_SW == STM32_SW_PLL
-#if STM32_PREDIV1SRC == STM32_PREDIV1SRC_PLL2
- RCC->CFGR2 |= STM32_PREDIV2 | STM32_PLL2MUL;
- RCC->CR |= RCC_CR_PLL2ON;
+ /* Settings of various dividers and multipliers in CFGR2.*/
+ RCC->CFGR2 = STM32_PLL3MUL | STM32_PLL2MUL | STM32_PREDIV2 |
+ STM32_PREDIV1 | STM32_PREDIV1SRC;
+
+ /* PLL2 setup, if activated.*/
+#if STM32_ACTIVATE_PLL2
+ RCC->CR |= RCC_CR_PLL2ON;
while (!(RCC->CR & RCC_CR_PLL2RDY))
- ; /* Waits until PLL is stable. */
+ ; /* Waits until PLL2 is stable. */
#endif
- /* PLL setup, it is only performed if the PLL is the selected source of
- the system clock else it is left disabled.*/
- RCC->CFGR2 |= STM32_PREDIV1 | STM32_PREDIV1SRC;
- RCC->CFGR |= STM32_PLLMUL | STM32_PLLSRC;
- RCC->CR |= RCC_CR_PLLON;
+ /* PLL3 setup, if activated.*/
+#if STM32_ACTIVATE_PLL3
+ RCC->CR |= RCC_CR_PLL3ON;
+ while (!(RCC->CR & RCC_CR_PLL3RDY))
+ ; /* Waits until PLL3 is stable. */
+#endif
+
+ /* PLL1 setup, if activated.*/
+#if STM32_ACTIVATE_PLL1
+ RCC->CFGR |= STM32_PLLMUL | STM32_PLLSRC;
+ RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY))
- ; /* Waits until PLL2 is stable. */
+ ; /* Waits until PLL1 is stable. */
#endif
/* Clock settings.*/
diff --git a/os/hal/platforms/STM32/hal_lld.h b/os/hal/platforms/STM32/hal_lld.h
index 0abac770c..b9c71dbbe 100644
--- a/os/hal/platforms/STM32/hal_lld.h
+++ b/os/hal/platforms/STM32/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -31,7 +32,7 @@
* - STM32F10X_LD for Performance Low Density devices.
* - STM32F10X_MD for Performance Medium Density devices.
* - STM32F10X_HD for Performance High Density devices.
- * - STM32F10X_XD for Performance eXtra Density devices.
+ * - STM32F10X_XL for Performance eXtra Density devices.
* - STM32F10X_CL for Connectivity Line devices.
* .
*
@@ -395,7 +396,7 @@
#define STM32_HAS_USB TRUE
#define STM32_HAS_OTG1 FALSE
-#elif defined(STM32F10X_XD)
+#elif defined(STM32F10X_XL)
/*
* Capability flags for Performance Line eXtra Density devices.
*/
diff --git a/os/hal/platforms/STM32/hal_lld_f100.h b/os/hal/platforms/STM32/hal_lld_f100.h
index 1ce918079..571682e38 100644
--- a/os/hal/platforms/STM32/hal_lld_f100.h
+++ b/os/hal/platforms/STM32/hal_lld_f100.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM32/hal_lld_f103.h b/os/hal/platforms/STM32/hal_lld_f103.h
index 6ea53571a..1f11da249 100644
--- a/os/hal/platforms/STM32/hal_lld_f103.h
+++ b/os/hal/platforms/STM32/hal_lld_f103.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -127,28 +128,19 @@
#define TIM1_CC_IRQHandler VectorAC /**< TIM1 Capture Compare. */
#define TIM2_IRQHandler VectorB0 /**< TIM2. */
#define TIM3_IRQHandler VectorB4 /**< TIM3. */
-#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
#define TIM4_IRQHandler VectorB8 /**< TIM4. */
-#endif
#define I2C1_EV_IRQHandler VectorBC /**< I2C1 Event. */
#define I2C1_ER_IRQHandler VectorC0 /**< I2C1 Error. */
-#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
#define I2C2_EV_IRQHandler VectorC4 /**< I2C2 Event. */
#define I2C2_ER_IRQHandler VectorC8 /**< I2C2 Error. */
-#endif
#define SPI1_IRQHandler VectorCC /**< SPI1. */
-#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
#define SPI2_IRQHandler VectorD0 /**< SPI2. */
-#endif
#define USART1_IRQHandler VectorD4 /**< USART1. */
#define USART2_IRQHandler VectorD8 /**< USART2. */
-#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
#define USART3_IRQHandler VectorDC /**< USART3. */
-#endif
#define EXTI15_10_IRQHandler VectorE0 /**< EXTI Line 15..10. */
#define RTCAlarm_IRQHandler VectorE4 /**< RTC Alarm through EXTI. */
#define USBWakeUp_IRQHandler VectorE8 /**< USB Wakeup from suspend. */
-#if defined(STM32F10X_HD) || defined(__DOXYGEN__)
#define TIM8_BRK_IRQHandler VectorEC /**< TIM8 Break. */
#define TIM8_UP_IRQHandler VectorF0 /**< TIM8 Update. */
#define TIM8_TRG_COM_IRQHandler VectorF4 /**< TIM8 Trigger and
@@ -167,7 +159,6 @@
#define DMA2_Ch2_IRQHandler Vector124 /**< DMA2 Channel2. */
#define DMA2_Ch3_IRQHandler Vector128 /**< DMA2 Channel3. */
#define DMA2_Ch4_5_IRQHandler Vector12C /**< DMA2 Channel4 & Channel5. */
-#endif
/*===========================================================================*/
/* Driver pre-compile time settings. */
diff --git a/os/hal/platforms/STM32/hal_lld_f105_f107.h b/os/hal/platforms/STM32/hal_lld_f105_f107.h
index d4477e705..ce8147ae0 100644
--- a/os/hal/platforms/STM32/hal_lld_f105_f107.h
+++ b/os/hal/platforms/STM32/hal_lld_f105_f107.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -171,9 +172,34 @@
/*===========================================================================*/
/**
+ * @brief PLL1 main switch.
+ * @note If this constant is set to @p TRUE then the PLL1 is initialized
+ * and started.
+ */
+#if !defined(STM32_ACTIVATE_PLL1) || defined(__DOXYGEN__)
+#define STM32_ACTIVATE_PLL1 TRUE
+#endif
+
+/**
+ * @brief PLL2 main switch.
+ * @note If this constant is set to @p TRUE then the PLL2 is initialized
+ * and started.
+ */
+#if !defined(STM32_ACTIVATE_PLL2) || defined(__DOXYGEN__)
+#define STM32_ACTIVATE_PLL2 TRUE
+#endif
+
+/**
+ * @brief PLL3 main switch.
+ * @note If this constant is set to @p TRUE then the PLL3 is initialized
+ * and started.
+ */
+#if !defined(STM32_ACTIVATE_PLL3) || defined(__DOXYGEN__)
+#define STM32_ACTIVATE_PLL3 TRUE
+#endif
+
+/**
* @brief Main clock source selection.
- * @note If the selected clock source is not the PLL then the PLL is not
- * initialized and started.
* @note The default value is calculated for a 72MHz system clock from
* a 25MHz crystal using both PLL and PLL2.
*/
@@ -183,8 +209,6 @@
/**
* @brief Clock source for the PLL.
- * @note This setting has only effect if the PLL is selected as the
- * system clock source.
* @note The default value is calculated for a 72MHz system clock from
* a 25MHz crystal using both PLL and PLL2.
*/
@@ -194,8 +218,6 @@
/**
* @brief PREDIV1 clock source.
- * @note This setting has only effect if the PLL is selected as the
- * system clock source.
* @note The default value is calculated for a 72MHz system clock from
* a 25MHz crystal using both PLL and PLL2.
*/
@@ -205,8 +227,6 @@
/**
* @brief PREDIV1 division factor.
- * @note This setting has only effect if the PLL is selected as the
- * system clock source.
* @note The allowed range is 1...16.
* @note The default value is calculated for a 72MHz system clock from
* a 25MHz crystal using both PLL and PLL2.
@@ -227,8 +247,6 @@
/**
* @brief PREDIV2 division factor.
- * @note This setting has only effect if the PLL2 is selected as the
- * clock source for the PLL.
* @note The allowed range is 1...16.
* @note The default value is calculated for a 72MHz system clock from
* a 25MHz crystal using both PLL and PLL2.
@@ -247,6 +265,15 @@
#endif
/**
+ * @brief PLL3 multiplier value.
+ * @note The default value is calculated for a 50MHz clock from
+ * a 25MHz crystal.
+ */
+#if !defined(STM32_PLL3MUL_VALUE) || defined(__DOXYGEN__)
+#define STM32_PLL3MUL_VALUE 10
+#endif
+
+/**
* @brief AHB prescaler value.
* @note The default value is calculated for a 72MHz system clock from
* a 25MHz crystal using both PLL and PLL2.
@@ -294,6 +321,13 @@
/* Derived constants and error checks. */
/*===========================================================================*/
+/* PLL2 usage check.*/
+#if STM32_ACTIVATE_PLL2 && \
+ (STM32_PREDIV1SRC != STM32_PREDIV1SRC_PLL2) && \
+ (STM32_MCO != STM32_MCO_PLL2)
+#error "PLL2 activated but not used"
+#endif
+
/**
* @brief PREDIV1 field.
*/
@@ -338,9 +372,22 @@
#error "invalid STM32_PLL2MUL_VALUE value specified"
#endif
-/* The following values are only used if PLL2 clock is selected as source
- for the PLL clock */
-#if (STM32_PREDIV1SRC == STM32_PREDIV1SRC_PLL2) || defined(__DOXYGEN__)
+/**
+ * @brief PLL3MUL field.
+ */
+#if ((STM32_PLL3MUL_VALUE >= 8) && (STM32_PLL3MUL_VALUE <= 14)) || \
+ defined(__DOXYGEN__)
+#define STM32_PLL3MUL ((STM32_PLL3MUL_VALUE - 2) << 12)
+#elif (STM32_PLL3MUL_VALUE == 16)
+#define STM32_PLL3MUL (14 << 12)
+#elif (STM32_PLL3MUL_VALUE == 20)
+#define STM32_PLL3MUL (15 << 12)
+#else
+#error "invalid STM32_PLL3MUL_VALUE value specified"
+#endif
+
+/* The following values are only used if PLL2 is activated */
+#if STM32_ACTIVATE_PLL2
/**
* @brief PLL2 input frequency.
*/
@@ -356,16 +403,54 @@
*/
#define STM32_PLL2CLKOUT (STM32_PLL2CLKIN * STM32_PLL2MUL_VALUE)
+/**
+ * @brief PLL2 VCO clock frequency.
+ */
+#define STM32_PLL2VCO (STM32_PLL2CLKOUT * 2)
+
/* PLL2 output frequency range check.*/
-#if (STM32_PLL2CLKOUT < 40000000) || (STM32_PLL2CLKOUT > 74000000)
-#error "STM32_PLL2CLKOUT outside acceptable range (40...74MHz)"
+#if (STM32_PLL2VCO < 80000000) || (STM32_PLL2VCO > 148000000)
+#error "STM32_PLL2VCO outside acceptable range (80...148MHz)"
+#endif
+#endif /* STM32_ACTIVATE_PLL2 */
+
+/* The following values are only used if PLL3 is activated */
+#if STM32_ACTIVATE_PLL3
+/**
+ * @brief PLL3 input frequency.
+ */
+#define STM32_PLL3CLKIN (STM32_HSECLK / STM32_PREDIV2_VALUE)
+
+/* PLL3 input frequency range check.*/
+#if (STM32_PLL3CLKIN < 3000000) || (STM32_PLL3CLKIN > 5000000)
+#error "STM32_PLL3CLKIN outside acceptable range (3...5MHz)"
#endif
-#endif /* STM32_PREDIV1SRC == STM32_PREDIV1SRC_PLL2 */
/**
+ * @brief PLL3 output clock frequency.
+ */
+#define STM32_PLL3CLKOUT (STM32_PLL3CLKIN * STM32_PLL3MUL_VALUE)
+
+/**
+ * @brief PLL3 VCO clock frequency.
+ */
+#define STM32_PLL3VCO (STM32_PLL3CLKOUT * 2)
+
+/* PLL3 output frequency range check.*/
+#if (STM32_PLL3VCO < 80000000) || (STM32_PLL3VCO > 148000000)
+#error "STM32_PLL3CLKOUT outside acceptable range (80...148MHz)"
+#endif
+#endif /* STM32_ACTIVATE_PLL3 */
+
+/* The following values are only used if PLL1 is activated */
+#if STM32_ACTIVATE_PLL1
+/**
* @brief PREDIV1 input frequency.
*/
#if (STM32_PREDIV1SRC == STM32_PREDIV1SRC_PLL2) || defined(__DOXYGEN__)
+#if !STM32_ACTIVATE_PLL2
+#error "PLL2 selected as clock source for STM32_PREDIV1SRC but not activated"
+#endif
#define STM32_PREDIV1CLK STM32_PLL2CLKOUT
#elif STM32_PREDIV1SRC == STM32_PREDIV1SRC_HSE
#define STM32_PREDIV1CLK STM32_HSECLK
@@ -377,9 +462,9 @@
* @brief PLL input clock frequency.
*/
#if (STM32_PLLSRC == STM32_PLLSRC_PREDIV1) || defined(__DOXYGEN__)
-#define STM32_PLLCLKIN (STM32_PREDIV1CLK / STM32_PREDIV1_VALUE)
+#define STM32_PLLCLKIN (STM32_PREDIV1CLK / STM32_PREDIV1_VALUE)
#elif STM32_PLLSRC == STM32_PLLSRC_HSI
-#define STM32_PLLCLKIN (STM32_HSICLK / 2)
+#define STM32_PLLCLKIN (STM32_HSICLK / 2)
#else
#error "invalid STM32_PLLSRC value specified"
#endif
@@ -392,17 +477,26 @@
/**
* @brief PLL output clock frequency.
*/
-#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE)
+#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE)
+
+/**
+ * @brief PLL VCO clock frequency.
+ */
+#define STM32_PLLVCO (STM32_PLLCLKOUT * 2)
/* PLL output frequency range check.*/
-#if (STM32_PLLCLKOUT < 18000000) || (STM32_PLLCLKOUT > 72000000)
-#error "STM32_PLLCLKOUT outside acceptable range (18...72MHz)"
+#if (STM32_PLLVCO < 36000000) || (STM32_PLLVCO > 144000000)
+#error "STM32_PLLVCO outside acceptable range (36...144MHz)"
#endif
+#endif /* STM32_ACTIVATE_PLL1 */
/**
* @brief System clock source.
*/
#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__)
+#if !STM32_ACTIVATE_PLL1
+#error "PLL1 selected as clock source for STM32_SYSCLK but not activated"
+#endif
#define STM32_SYSCLK STM32_PLLCLKOUT
#elif (STM32_SW == STM32_SW_HSI)
#define STM32_SYSCLK STM32_HSICLK
@@ -515,9 +609,9 @@
* @brief OTG frequency.
*/
#if (STM32_OTGFSPRE == STM32_OTGFSPRE_DIV3) || defined(__DOXYGEN__)
-#define STM32_OTGFSCLK ((STM32_PLLCLKOUT * 2) / 3)
+#define STM32_OTGFSCLK (STM32_PLLVCO / 3)
#elif (STM32_OTGFSPRE == STM32_OTGFSPRE_DIV2)
-#define STM32_OTGFSCLK STM32_PLLCLKOUT
+#define STM32_OTGFSCLK (STM32_PLLVCO / 2)
#else
#error "invalid STM32_OTGFSPRE value specified"
#endif
diff --git a/os/hal/platforms/STM32/icu_lld.c b/os/hal/platforms/STM32/icu_lld.c
new file mode 100644
index 000000000..ae3287ef9
--- /dev/null
+++ b/os/hal/platforms/STM32/icu_lld.c
@@ -0,0 +1,425 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/icu_lld.c
+ * @brief STM32 ICU subsystem low level driver header.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief ICUD1 driver identifier.
+ * @note The driver ICUD1 allocates the complex timer TIM1 when enabled.
+ */
+#if STM32_ICU_USE_TIM1 || defined(__DOXYGEN__)
+ICUDriver ICUD1;
+#endif
+
+/**
+ * @brief ICUD2 driver identifier.
+ * @note The driver ICUD1 allocates the timer TIM2 when enabled.
+ */
+#if STM32_ICU_USE_TIM2 || defined(__DOXYGEN__)
+ICUDriver ICUD2;
+#endif
+
+/**
+ * @brief ICUD3 driver identifier.
+ * @note The driver ICUD1 allocates the timer TIM3 when enabled.
+ */
+#if STM32_ICU_USE_TIM3 || defined(__DOXYGEN__)
+ICUDriver ICUD3;
+#endif
+
+/**
+ * @brief ICUD4 driver identifier.
+ * @note The driver ICUD4 allocates the timer TIM4 when enabled.
+ */
+#if STM32_ICU_USE_TIM4 || defined(__DOXYGEN__)
+ICUDriver ICUD4;
+#endif
+
+/**
+ * @brief ICUD5 driver identifier.
+ * @note The driver ICUD5 allocates the timer TIM5 when enabled.
+ */
+#if STM32_ICU_USE_TIM5 || defined(__DOXYGEN__)
+ICUDriver ICUD5;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Shared IRQ handler.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ */
+static void icu_lld_serve_interrupt(ICUDriver *icup) {
+ uint16_t sr;
+
+ sr = icup->tim->SR & icup->tim->DIER;
+ icup->tim->SR = 0;
+ if ((sr & TIM_SR_CC1IF) != 0)
+ _icu_isr_invoke_period_cb(icup);
+ if ((sr & TIM_SR_CC2IF) != 0)
+ _icu_isr_invoke_width_cb(icup);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_ICU_USE_TIM1
+/**
+ * @brief TIM1 compare interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM1_CC_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD1);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_ICU_USE_TIM1 */
+
+#if STM32_ICU_USE_TIM2
+/**
+ * @brief TIM2 compare interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM2_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD2);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_ICU_USE_TIM2 */
+
+#if STM32_ICU_USE_TIM3
+/**
+ * @brief TIM3 compare interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM3_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD3);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_ICU_USE_TIM3 */
+
+#if STM32_ICU_USE_TIM4
+/**
+ * @brief TIM4 compare interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM4_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD4);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_ICU_USE_TIM4 */
+
+#if STM32_ICU_USE_TIM5
+/**
+ * @brief TIM5 compare interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(TIM5_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD5);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_ICU_USE_TIM5 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ICU driver initialization.
+ *
+ * @notapi
+ */
+void icu_lld_init(void) {
+
+#if STM32_ICU_USE_TIM1
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD1);
+ ICUD1.tim = TIM1;
+#endif
+
+#if STM32_ICU_USE_TIM2
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD2);
+ ICUD2.tim = TIM2;
+#endif
+
+#if STM32_ICU_USE_TIM3
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD3);
+ ICUD3.tim = TIM3;
+#endif
+
+#if STM32_ICU_USE_TIM4
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD4);
+ ICUD4.tim = TIM4;
+#endif
+
+#if STM32_ICU_USE_TIM5
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD5);
+ ICUD5.tim = TIM5;
+#endif
+}
+
+/**
+ * @brief Configures and activates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_start(ICUDriver *icup) {
+ uint32_t clock, psc;
+
+ if (icup->state == ICU_STOP) {
+ /* Clock activation and timer reset.*/
+#if STM32_ICU_USE_TIM1
+ if (&ICUD1 == icup) {
+ RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
+ RCC->APB2RSTR = RCC_APB2RSTR_TIM1RST;
+ RCC->APB2RSTR = 0;
+ NVICEnableVector(TIM1_CC_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_ICU_TIM1_IRQ_PRIORITY));
+ clock = STM32_TIMCLK2;
+ }
+#endif
+#if STM32_ICU_USE_TIM2
+ if (&ICUD2 == icup) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM2_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_ICU_TIM2_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
+ }
+#endif
+#if STM32_ICU_USE_TIM3
+ if (&ICUD3 == icup) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM3RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM3_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_ICU_TIM3_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
+ }
+#endif
+#if STM32_ICU_USE_TIM4
+ if (&ICUD4 == icup) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM4RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM4_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_ICU_TIM4_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
+ }
+#endif
+
+#if STM32_ICU_USE_TIM5
+ if (&ICUD5 == icup) {
+ RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM5RST;
+ RCC->APB1RSTR = 0;
+ NVICEnableVector(TIM5_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_ICU_TIM5_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
+ }
+#endif
+ }
+ else {
+ /* Driver re-configuration scenario, it must be stopped first.*/
+ icup->tim->CR1 = 0; /* Timer disabled. */
+ icup->tim->DIER = 0; /* All IRQs disabled. */
+ icup->tim->SR = 0; /* Clear eventual pending IRQs. */
+ icup->tim->CCR1 = 0; /* Comparator 1 disabled. */
+ icup->tim->CCR2 = 0; /* Comparator 2 disabled. */
+ icup->tim->CNT = 0; /* Counter reset to zero. */
+ }
+
+ /* Timer configuration.*/
+ psc = (clock / icup->config->frequency) - 1;
+ chDbgAssert((psc <= 0xFFFF) &&
+ ((psc + 1) * icup->config->frequency) == clock,
+ "icu_lld_start(), #1", "invalid frequency");
+ icup->tim->PSC = (uint16_t)psc;
+ icup->tim->ARR = 0xFFFF;
+
+ /* CCMR1_CC1S = 01 = CH1 Input on TI1.
+ CCMR1_CC2S = 10 = CH2 Input on TI2.*/
+ icup->tim->CCMR1 = TIM_CCMR1_CC1S_0 |
+ TIM_CCMR1_CC2S_1;
+ /* SMCR_TS = 101, input is TI1FP1.
+ SMCR_SMS = 100, reset on rising edge.*/
+ icup->tim->SMCR = TIM_SMCR_TS_2 | TIM_SMCR_TS_0 |
+ TIM_SMCR_SMS_2;
+ /* The CCER settings depend on the selected trigger mode.
+ ICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge.
+ ICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.*/
+ if (icup->config->mode == ICU_INPUT_ACTIVE_HIGH)
+ icup->tim->CCER = TIM_CCER_CC1E |
+ TIM_CCER_CC2E | TIM_CCER_CC2P;
+ else
+ icup->tim->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P |
+ TIM_CCER_CC2E;
+}
+
+/**
+ * @brief Deactivates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_stop(ICUDriver *icup) {
+
+ if (icup->state == ICU_READY) {
+ /* Clock deactivation.*/
+ icup->tim->CR1 = 0; /* Timer disabled. */
+ icup->tim->DIER = 0; /* All IRQs disabled. */
+ icup->tim->SR = 0; /* Clear eventual pending IRQs. */
+
+#if STM32_ICU_USE_TIM1
+ if (&ICUD1 == icup) {
+ NVICDisableVector(TIM1_CC_IRQn);
+ RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN;
+ }
+#endif
+ }
+#if STM32_ICU_USE_TIM2
+ if (&ICUD2 == icup) {
+ NVICDisableVector(TIM2_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM2EN;
+ }
+#endif
+#if STM32_ICU_USE_TIM3
+ if (&ICUD3 == icup) {
+ NVICDisableVector(TIM3_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM3EN;
+ }
+#endif
+#if STM32_ICU_USE_TIM4
+ if (&ICUD4 == icup) {
+ NVICDisableVector(TIM4_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM4EN;
+ }
+#endif
+#if STM32_ICU_USE_TIM5
+ if (&ICUD5 == icup) {
+ NVICDisableVector(TIM5_IRQn);
+ RCC->APB1ENR &= ~RCC_APB1ENR_TIM5EN;
+ }
+#endif
+}
+
+/**
+ * @brief Enables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_enable(ICUDriver *icup) {
+
+ icup->tim->SR = 0; /* Clear pending IRQs (if any). */
+ if (icup->config->period_cb != NULL)
+ icup->tim->DIER |= TIM_DIER_CC1IE;
+ if (icup->config->width_cb != NULL)
+ icup->tim->DIER |= TIM_DIER_CC2IE;
+ icup->tim->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
+}
+
+/**
+ * @brief Disables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_disable(ICUDriver *icup) {
+
+ icup->tim->CR1 = 0; /* Initially stopped. */
+ icup->tim->SR = 0; /* Clear pending IRQs (if any). */
+ icup->tim->DIER = 0; /* Interrupts disabled. */
+}
+
+#endif /* HAL_USE_ICU */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/icu_lld.h b/os/hal/platforms/STM32/icu_lld.h
new file mode 100644
index 000000000..b98b8bf86
--- /dev/null
+++ b/os/hal/platforms/STM32/icu_lld.h
@@ -0,0 +1,290 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/icu_lld.h
+ * @brief STM32 ICU subsystem low level driver header.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#ifndef _ICU_LLD_H_
+#define _ICU_LLD_H_
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief ICUD1 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ICU_USE_TIM1) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM1 TRUE
+#endif
+
+/**
+ * @brief ICUD2 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ICU_USE_TIM2) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM2 TRUE
+#endif
+
+/**
+ * @brief ICUD3 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD3 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ICU_USE_TIM3) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM3 TRUE
+#endif
+
+/**
+ * @brief ICUD4 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ICU_USE_TIM4) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM4 TRUE
+#endif
+
+/**
+ * @brief ICUD5 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD5 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ICU_USE_TIM5) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM5 TRUE
+#endif
+
+/**
+ * @brief ICUD1 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM1_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD2 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM2_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD3 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM3_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD4 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM4_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD5 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM5_IRQ_PRIORITY 7
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_ICU_USE_TIM1 && !STM32_HAS_TIM1
+#error "TIM1 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM2 && !STM32_HAS_TIM2
+#error "TIM2 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM3 && !STM32_HAS_TIM3
+#error "TIM3 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM4 && !STM32_HAS_TIM4
+#error "TIM4 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM5 && !STM32_HAS_TIM5
+#error "TIM5 not present in the selected device"
+#endif
+
+#if !STM32_ICU_USE_TIM1 && !STM32_ICU_USE_TIM2 && \
+ !STM32_ICU_USE_TIM3 && !STM32_ICU_USE_TIM4 && \
+ !STM32_ICU_USE_TIM5
+#error "ICU driver activated but no TIM peripheral assigned"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ICU driver mode.
+ */
+typedef enum {
+ ICU_INPUT_ACTIVE_HIGH = 0, /**< Trigger on rising edge. */
+ ICU_INPUT_ACTIVE_LOW = 1, /**< Trigger on falling edge. */
+} icumode_t;
+
+/**
+ * @brief ICU frequency type.
+ */
+typedef uint32_t icufreq_t;
+
+/**
+ * @brief ICU counter type.
+ */
+typedef uint16_t icucnt_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Driver mode.
+ */
+ icumode_t mode;
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ icufreq_t frequency;
+ /**
+ * @brief Callback for pulse width measurement.
+ */
+ icucallback_t width_cb;
+ /**
+ * @brief Callback for cycle period measurement.
+ */
+ icucallback_t period_cb;
+ /* End of the mandatory fields.*/
+} ICUConfig;
+
+/**
+ * @brief Structure representing an ICU driver.
+ */
+struct ICUDriver {
+ /**
+ * @brief Driver state.
+ */
+ icustate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const ICUConfig *config;
+#if defined(ICU_DRIVER_EXT_FIELDS)
+ ICU_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the TIMx registers block.
+ */
+ TIM_TypeDef *tim;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Returns the width of the latest pulse.
+ * @details The pulse width is defined as number of ticks between the start
+ * edge and the stop edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @notapi
+ */
+#define icu_lld_get_width(icup) ((icup)->tim->CCR2 + 1)
+
+/**
+ * @brief Returns the width of the latest cycle.
+ * @details The cycle width is defined as number of ticks between a start
+ * edge and the next start edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @notapi
+ */
+#define icu_lld_get_period(icup) ((icup)->tim->CCR1 + 1)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_ICU_USE_TIM1 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD1;
+#endif
+
+#if STM32_ICU_USE_TIM2 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD2;
+#endif
+
+#if STM32_ICU_USE_TIM3 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD3;
+#endif
+
+#if STM32_ICU_USE_TIM4 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD4;
+#endif
+
+#if STM32_ICU_USE_TIM5 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD5;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void icu_lld_init(void);
+ void icu_lld_start(ICUDriver *icup);
+ void icu_lld_stop(ICUDriver *icup);
+ void icu_lld_enable(ICUDriver *icup);
+ void icu_lld_disable(ICUDriver *icup);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ICU */
+
+#endif /* _ICU_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/pal_lld.c b/os/hal/platforms/STM32/pal_lld.c
index ac90883f7..c56996db7 100644
--- a/os/hal/platforms/STM32/pal_lld.c
+++ b/os/hal/platforms/STM32/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -31,25 +32,15 @@
#if HAL_USE_PAL || defined(__DOXYGEN__)
#if STM32_HAS_GPIOG
-#define APB2_RST_MASK (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | \
- RCC_APB2RSTR_IOPCRST | RCC_APB2RSTR_IOPDRST | \
- RCC_APB2RSTR_IOPERST | RCC_APB2RSTR_IOPFRST | \
- RCC_APB2RSTR_IOPGRST | RCC_APB2RSTR_AFIORST);
#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
RCC_APB2ENR_IOPEEN | RCC_APB2ENR_IOPFEN | \
RCC_APB2ENR_IOPGEN | RCC_APB2ENR_AFIOEN)
#elif STM32_HAS_GPIOE
-#define APB2_RST_MASK (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | \
- RCC_APB2RSTR_IOPCRST | RCC_APB2RSTR_IOPDRST | \
- RCC_APB2RSTR_IOPERST | RCC_APB2RSTR_AFIORST);
#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
RCC_APB2ENR_IOPEEN | RCC_APB2ENR_AFIOEN)
#else
-#define APB2_RST_MASK (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | \
- RCC_APB2RSTR_IOPCRST | RCC_APB2RSTR_IOPDRST | \
- RCC_APB2RSTR_AFIORST)
#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
RCC_APB2ENR_AFIOEN)
@@ -91,11 +82,8 @@ void _pal_lld_init(const PALConfig *config) {
RCC->APB2ENR |= APB2_EN_MASK;
/*
- * Resets the GPIO ports and AFIO.
+ * Initial GPIO setup.
*/
- RCC->APB2RSTR = APB2_RST_MASK;
- RCC->APB2RSTR = 0;
-
GPIOA->ODR = config->PAData.odr;
GPIOA->CRH = config->PAData.crh;
GPIOA->CRL = config->PAData.crl;
diff --git a/os/hal/platforms/STM32/pal_lld.h b/os/hal/platforms/STM32/pal_lld.h
index a6d1236ae..2919c91f6 100644
--- a/os/hal/platforms/STM32/pal_lld.h
+++ b/os/hal/platforms/STM32/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -278,10 +279,9 @@ typedef GPIO_TypeDef * ioportid_t;
*
* @notapi
*/
-#define pal_lld_writegroup(port, mask, offset, bits) { \
- (port)->BSRR = ((~(bits) & (mask)) << (16 + (offset))) | \
- (((bits) & (mask)) << (offset)); \
-}
+#define pal_lld_writegroup(port, mask, offset, bits) \
+ ((port)->BSRR = ((~(bits) & (mask)) << (16 + (offset))) | \
+ (((bits) & (mask)) << (offset)))
/**
* @brief Pads group mode setup.
diff --git a/os/hal/platforms/STM32/platform.dox b/os/hal/platforms/STM32/platform.dox
index 91f0addca..50ab84f38 100644
--- a/os/hal/platforms/STM32/platform.dox
+++ b/os/hal/platforms/STM32/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -61,7 +62,7 @@
* - Programmable ADC interrupt priority level.
* - Programmable DMA bus priority for each DMA channel.
* - Programmable DMA interrupt priority for each DMA channel.
- * - Programmable DMA error hook for each DMA channel.
+ * - Programmable DMA error hook.
* .
* @ingroup STM32_DRIVERS
*/
@@ -100,7 +101,45 @@
*/
/**
- * @defgroup STM32_PAL STM32 GPIO Support
+ * @defgroup STM32_GPT STM32 GPT Support
+ * @details The STM32 GPT driver uses the TIMx peripherals.
+ *
+ * @section stm32_gpt_1 Supported HW resources
+ * - TIM1.
+ * - TIM2.
+ * - TIM3.
+ * - TIM4.
+ * - TIM5.
+ * .
+ * @section stm32_gpt_2 STM32 GPT driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable TIMx interrupts priority level.
+ * .
+ * @ingroup STM32_DRIVERS
+ */
+
+/**
+ * @defgroup STM32_ICU STM32 ICU Support
+ * @details The STM32 ICU driver uses the TIMx peripherals.
+ *
+ * @section stm32_icu_1 Supported HW resources
+ * - TIM1.
+ * - TIM2.
+ * - TIM3.
+ * - TIM4.
+ * - TIM5.
+ * .
+ * @section stm32_icu_2 STM32 ICU driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable TIMx interrupts priority level.
+ * .
+ * @ingroup STM32_DRIVERS
+ */
+
+/**
+ * @defgroup STM32_PAL STM32 PAL Support
* @details The STM32 PAL driver uses the GPIO peripherals.
*
* @section stm32_pal_1 Supported HW resources
@@ -158,6 +197,7 @@
* - TIM2.
* - TIM3.
* - TIM4.
+ * - TIM5.
* .
* @section stm32_pwm_2 STM32 PWM driver implementation features
* - Each timer can be independently enabled and programmed. Unused
@@ -169,32 +209,24 @@
*/
/**
- * @defgroup STM32_SPI STM32 SPI Support
- * @details The SPI driver supports the STM32 SPI peripherals using DMA
- * channels for maximum performance.
+ * @defgroup STM32_SDC STM32 SDC Support
+ * @details The STM32 SDC driver uses the SDIO peripheral.
*
- * @section stm32_spi_1 Supported HW resources
- * - SPI1.
- * - SPI2.
- * - SPI3 (where present).
- * - DMA1.
- * - DMA2 (where present).
+ * @section stm32_sdc_1 Supported HW resources
+ * - SDIO.
+ * - DMA2.
* .
- * @section stm32_spi_2 STM32 SPI driver implementation features
+ * @section stm32_sdc_2 STM32 SDC driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
- * - Each SPI can be independently enabled and programmed. Unused
- * peripherals are left in low power mode.
- * - Programmable interrupt priority levels for each SPI.
+ * - Programmable interrupt priority.
* - DMA is used for receiving and transmitting.
* - Programmable DMA bus priority for each DMA channel.
- * - Programmable DMA interrupt priority for each DMA channel.
- * - Programmable DMA error hook for each DMA channel.
* .
* @ingroup STM32_DRIVERS
*/
/**
- * @defgroup STM32_SERIAL STM32 USART Support (buffered)
+ * @defgroup STM32_SERIAL STM32 Serial Support
* @details The STM32 Serial driver uses the USART/UART peripherals in a
* buffered, interrupt driven, implementation.
*
@@ -217,7 +249,32 @@
*/
/**
- * @defgroup STM32_UART STM32 USART Support (unbuffered)
+ * @defgroup STM32_SPI STM32 SPI Support
+ * @details The SPI driver supports the STM32 SPI peripherals using DMA
+ * channels for maximum performance.
+ *
+ * @section stm32_spi_1 Supported HW resources
+ * - SPI1.
+ * - SPI2.
+ * - SPI3 (where present).
+ * - DMA1.
+ * - DMA2 (where present).
+ * .
+ * @section stm32_spi_2 STM32 SPI driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Each SPI can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable interrupt priority levels for each SPI.
+ * - DMA is used for receiving and transmitting.
+ * - Programmable DMA bus priority for each DMA channel.
+ * - Programmable DMA interrupt priority for each DMA channel.
+ * - Programmable DMA error hook.
+ * .
+ * @ingroup STM32_DRIVERS
+ */
+
+/**
+ * @defgroup STM32_UART STM32 UART Support
* @details The UART driver supports the STM32 USART peripherals using DMA
* channels for maximum performance.
*
@@ -226,6 +283,7 @@
* - USART1.
* - USART2.
* - USART3 (where present).
+ * - UART4 (where present).
* - DMA1.
* - DMA2 (where present).
* .
@@ -237,7 +295,23 @@
* - DMA is used for receiving and transmitting.
* - Programmable DMA bus priority for each DMA channel.
* - Programmable DMA interrupt priority for each DMA channel.
- * - Programmable DMA error hook for each DMA channel.
+ * - Programmable DMA error hook.
+ * .
+ * @ingroup STM32_DRIVERS
+ */
+
+/**
+ * @defgroup STM32_USB STM32 USB Support
+ * @details The USB driver supports the STM32 USB peripheral.
+ *
+ * @section stm32_usb_1 Supported HW resources
+ * The USB driver can support any of the following hardware resources:
+ * - USB.
+ * .
+ * @section stm32_usb_2 STM32 USB driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Programmable interrupt priority levels.
+ * - Each endpoint programmable in Control, Bulk and Interrupt modes.
* .
* @ingroup STM32_DRIVERS
*/
diff --git a/os/hal/platforms/STM32/platform.mk b/os/hal/platforms/STM32/platform.mk
index 35717687f..02f090e5e 100644
--- a/os/hal/platforms/STM32/platform.mk
+++ b/os/hal/platforms/STM32/platform.mk
@@ -2,8 +2,11 @@
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32/hal_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/adc_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/can_lld.c \
+ ${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \
+ ${CHIBIOS}/os/hal/platforms/STM32/icu_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/pal_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/pwm_lld.c \
+ ${CHIBIOS}/os/hal/platforms/STM32/sdc_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 \
diff --git a/os/hal/platforms/STM32/pwm_lld.c b/os/hal/platforms/STM32/pwm_lld.c
index f78896e95..bb6dad8f2 100644
--- a/os/hal/platforms/STM32/pwm_lld.c
+++ b/os/hal/platforms/STM32/pwm_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -47,40 +48,40 @@
/*===========================================================================*/
/**
- * @brief PWM1 driver identifier.
- * @note The driver PWM1 allocates the complex timer TIM1 when enabled.
+ * @brief PWMD1 driver identifier.
+ * @note The driver PWMD1 allocates the complex timer TIM1 when enabled.
*/
#if STM32_PWM_USE_TIM1 || defined(__DOXYGEN__)
PWMDriver PWMD1;
#endif
/**
- * @brief PWM2 driver identifier.
- * @note The driver PWM2 allocates the timer TIM2 when enabled.
+ * @brief PWMD2 driver identifier.
+ * @note The driver PWMD2 allocates the timer TIM2 when enabled.
*/
#if STM32_PWM_USE_TIM2 || defined(__DOXYGEN__)
PWMDriver PWMD2;
#endif
/**
- * @brief PWM3 driver identifier.
- * @note The driver PWM3 allocates the timer TIM3 when enabled.
+ * @brief PWMD3 driver identifier.
+ * @note The driver PWMD3 allocates the timer TIM3 when enabled.
*/
#if STM32_PWM_USE_TIM3 || defined(__DOXYGEN__)
PWMDriver PWMD3;
#endif
/**
- * @brief PWM4 driver identifier.
- * @note The driver PWM4 allocates the timer TIM4 when enabled.
+ * @brief PWMD4 driver identifier.
+ * @note The driver PWMD4 allocates the timer TIM4 when enabled.
*/
#if STM32_PWM_USE_TIM4 || defined(__DOXYGEN__)
PWMDriver PWMD4;
#endif
/**
- * @brief PWM5 driver identifier.
- * @note The driver PWM5 allocates the timer TIM5 when enabled.
+ * @brief PWMD5 driver identifier.
+ * @note The driver PWMD5 allocates the timer TIM5 when enabled.
*/
#if STM32_PWM_USE_TIM5 || defined(__DOXYGEN__)
PWMDriver PWMD5;
@@ -101,24 +102,26 @@ PWMDriver PWMD5;
* @note It is assumed that the various sources are only activated if the
* associated callback pointer is not equal to @p NULL in order to not
* perform an extra check in a potentially critical interrupt handler.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
*/
static void serve_interrupt(PWMDriver *pwmp) {
uint16_t sr;
- sr = pwmp->pd_tim->SR;
- sr &= pwmp->pd_tim->DIER;
- pwmp->pd_tim->SR = ~(TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF |
- TIM_SR_CC4IF | TIM_SR_UIF);
+ sr = pwmp->tim->SR;
+ sr &= pwmp->tim->DIER;
+ pwmp->tim->SR = ~(TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF |
+ TIM_SR_CC4IF | TIM_SR_UIF);
if ((sr & TIM_SR_CC1IF) != 0)
- pwmp->pd_config->pc_channels[0].pcc_callback(pwmp);
+ pwmp->config->channels[0].callback(pwmp);
if ((sr & TIM_SR_CC2IF) != 0)
- pwmp->pd_config->pc_channels[1].pcc_callback(pwmp);
+ pwmp->config->channels[1].callback(pwmp);
if ((sr & TIM_SR_CC3IF) != 0)
- pwmp->pd_config->pc_channels[2].pcc_callback(pwmp);
+ pwmp->config->channels[2].callback(pwmp);
if ((sr & TIM_SR_CC4IF) != 0)
- pwmp->pd_config->pc_channels[3].pcc_callback(pwmp);
+ pwmp->config->channels[3].callback(pwmp);
if ((sr & TIM_SR_UIF) != 0)
- pwmp->pd_config->pc_callback(pwmp);
+ pwmp->config->callback(pwmp);
}
#endif /* STM32_PWM_USE_TIM2 || ... || STM32_PWM_USE_TIM5 */
@@ -140,7 +143,7 @@ CH_IRQ_HANDLER(TIM1_UP_IRQHandler) {
CH_IRQ_PROLOGUE();
TIM1->SR = ~TIM_SR_UIF;
- PWMD1.pd_config->pc_callback(&PWMD1);
+ PWMD1.config->callback(&PWMD1);
CH_IRQ_EPILOGUE();
}
@@ -161,13 +164,13 @@ CH_IRQ_HANDLER(TIM1_CC_IRQHandler) {
sr = TIM1->SR & TIM1->DIER;
TIM1->SR = ~(TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF | TIM_SR_CC4IF);
if ((sr & TIM_SR_CC1IF) != 0)
- PWMD1.pd_config->pc_channels[0].pcc_callback(&PWMD1);
+ PWMD1.config->channels[0].callback(&PWMD1);
if ((sr & TIM_SR_CC2IF) != 0)
- PWMD1.pd_config->pc_channels[1].pcc_callback(&PWMD1);
+ PWMD1.config->channels[1].callback(&PWMD1);
if ((sr & TIM_SR_CC3IF) != 0)
- PWMD1.pd_config->pc_channels[2].pcc_callback(&PWMD1);
+ PWMD1.config->channels[2].callback(&PWMD1);
if ((sr & TIM_SR_CC4IF) != 0)
- PWMD1.pd_config->pc_channels[3].pcc_callback(&PWMD1);
+ PWMD1.config->channels[3].callback(&PWMD1);
CH_IRQ_EPILOGUE();
}
@@ -249,75 +252,50 @@ CH_IRQ_HANDLER(TIM5_IRQHandler) {
void pwm_lld_init(void) {
#if STM32_PWM_USE_TIM1
- /* TIM1 reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB2RSTR = RCC_APB2RSTR_TIM1RST;
- RCC->APB2RSTR = 0;
-
/* Driver initialization.*/
pwmObjectInit(&PWMD1);
- PWMD1.pd_enabled_channels = 0;
- PWMD1.pd_tim = TIM1;
+ PWMD1.tim = TIM1;
#endif
#if STM32_PWM_USE_TIM2
- /* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST;
- RCC->APB1RSTR = 0;
-
/* Driver initialization.*/
pwmObjectInit(&PWMD2);
- PWMD2.pd_enabled_channels = 0;
- PWMD2.pd_tim = TIM2;
+ PWMD2.tim = TIM2;
#endif
#if STM32_PWM_USE_TIM3
- /* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB1RSTR = RCC_APB1RSTR_TIM3RST;
- RCC->APB1RSTR = 0;
-
/* Driver initialization.*/
pwmObjectInit(&PWMD3);
- PWMD3.pd_enabled_channels = 0;
- PWMD3.pd_tim = TIM3;
+ PWMD3.tim = TIM3;
#endif
#if STM32_PWM_USE_TIM4
- /* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB1RSTR = RCC_APB1RSTR_TIM4RST;
- RCC->APB1RSTR = 0;
-
/* Driver initialization.*/
pwmObjectInit(&PWMD4);
- PWMD4.pd_enabled_channels = 0;
- PWMD4.pd_tim = TIM4;
+ PWMD4.tim = TIM4;
#endif
#if STM32_PWM_USE_TIM5
- /* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB1RSTR = RCC_APB1RSTR_TIM5RST;
- RCC->APB1RSTR = 0;
-
/* Driver initialization.*/
pwmObjectInit(&PWMD5);
- PWMD5.pd_enabled_channels = 0;
- PWMD5.pd_tim = TIM5;
+ PWMD5.tim = TIM5;
#endif
}
/**
* @brief Configures and activates the PWM peripheral.
+ * @note Starting a driver that is already in the @p PWM_READY state
+ * disables all the active channels.
*
* @param[in] pwmp pointer to a @p PWMDriver object
*
* @notapi
*/
void pwm_lld_start(PWMDriver *pwmp) {
+ uint32_t clock, psc;
uint16_t ccer;
- /* Reset channels.*/
- pwmp->pd_enabled_channels = 0; /* All channels disabled. */
-
- if (pwmp->pd_state == PWM_STOP) {
+ if (pwmp->state == PWM_STOP) {
/* Clock activation and timer reset.*/
#if STM32_PWM_USE_TIM1
if (&PWMD1 == pwmp) {
@@ -328,6 +306,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
CORTEX_PRIORITY_MASK(STM32_PWM_TIM1_IRQ_PRIORITY));
NVICEnableVector(TIM1_CC_IRQn,
CORTEX_PRIORITY_MASK(STM32_PWM_TIM1_IRQ_PRIORITY));
+ clock = STM32_TIMCLK2;
}
#endif
#if STM32_PWM_USE_TIM2
@@ -337,6 +316,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
RCC->APB1RSTR = 0;
NVICEnableVector(TIM2_IRQn,
CORTEX_PRIORITY_MASK(STM32_PWM_TIM2_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
}
#endif
#if STM32_PWM_USE_TIM3
@@ -346,6 +326,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
RCC->APB1RSTR = 0;
NVICEnableVector(TIM3_IRQn,
CORTEX_PRIORITY_MASK(STM32_PWM_TIM3_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
}
#endif
#if STM32_PWM_USE_TIM4
@@ -355,6 +336,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
RCC->APB1RSTR = 0;
NVICEnableVector(TIM4_IRQn,
CORTEX_PRIORITY_MASK(STM32_PWM_TIM4_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
}
#endif
@@ -365,41 +347,45 @@ void pwm_lld_start(PWMDriver *pwmp) {
RCC->APB1RSTR = 0;
NVICEnableVector(TIM5_IRQn,
CORTEX_PRIORITY_MASK(STM32_PWM_TIM5_IRQ_PRIORITY));
+ clock = STM32_TIMCLK1;
}
#endif
-
/* All channels configured in PWM1 mode with preload enabled and will
stay that way until the driver is stopped.*/
- pwmp->pd_tim->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
- TIM_CCMR1_OC1PE |
- TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 |
- TIM_CCMR1_OC2PE;
- pwmp->pd_tim->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 |
- TIM_CCMR2_OC3PE |
- TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 |
- TIM_CCMR2_OC4PE;
+ pwmp->tim->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
+ TIM_CCMR1_OC1PE |
+ TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 |
+ TIM_CCMR1_OC2PE;
+ pwmp->tim->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 |
+ TIM_CCMR2_OC3PE |
+ TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 |
+ TIM_CCMR2_OC4PE;
}
else {
/* Driver re-configuration scenario, it must be stopped first.*/
- /* Really required ?????????? */
- pwmp->pd_tim->CR1 = 0; /* Timer stopped. */
- pwmp->pd_tim->CR2 = 0; /* Timer stopped. */
- pwmp->pd_tim->SMCR = 0; /* Slave mode disabled. */
- pwmp->pd_tim->CCR1 = 0; /* Comparator 1 disabled. */
- pwmp->pd_tim->CCR2 = 0; /* Comparator 2 disabled. */
- pwmp->pd_tim->CCR3 = 0; /* Comparator 3 disabled. */
- pwmp->pd_tim->CCR4 = 0; /* Comparator 4 disabled. */
- pwmp->pd_tim->CNT = 0;
+ pwmp->tim->CR1 = 0; /* Timer disabled. */
+ pwmp->tim->DIER = 0; /* All IRQs disabled. */
+ pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */
+ pwmp->tim->CCR1 = 0; /* Comparator 1 disabled. */
+ pwmp->tim->CCR2 = 0; /* Comparator 2 disabled. */
+ pwmp->tim->CCR3 = 0; /* Comparator 3 disabled. */
+ pwmp->tim->CCR4 = 0; /* Comparator 4 disabled. */
+ pwmp->tim->CNT = 0; /* Counter reset to zero. */
}
/* Timer configuration.*/
- pwmp->pd_tim->CR2 = pwmp->pd_config->pc_cr2;
- pwmp->pd_tim->PSC = pwmp->pd_config->pc_psc;
- pwmp->pd_tim->ARR = pwmp->pd_config->pc_arr;
+ psc = (clock / pwmp->config->frequency) - 1;
+ chDbgAssert((psc <= 0xFFFF) &&
+ ((psc + 1) * pwmp->config->frequency) == clock,
+ "pwm_lld_start(), #1", "invalid frequency");
+ pwmp->tim->PSC = (uint16_t)psc;
+ pwmp->tim->ARR = (uint16_t)(pwmp->period - 1);
+ pwmp->tim->CR2 = pwmp->config->cr2;
+
/* Output enables and polarities setup.*/
ccer = 0;
- switch (pwmp->pd_config->pc_channels[0].pcc_mode) {
+ switch (pwmp->config->channels[0].mode & PWM_OUTPUT_MASK) {
case PWM_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC1P;
case PWM_OUTPUT_ACTIVE_HIGH:
@@ -407,7 +393,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
default:
;
}
- switch (pwmp->pd_config->pc_channels[1].pcc_mode) {
+ switch (pwmp->config->channels[1].mode & PWM_OUTPUT_MASK) {
case PWM_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC2P;
case PWM_OUTPUT_ACTIVE_HIGH:
@@ -415,7 +401,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
default:
;
}
- switch (pwmp->pd_config->pc_channels[2].pcc_mode) {
+ switch (pwmp->config->channels[2].mode & PWM_OUTPUT_MASK) {
case PWM_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC3P;
case PWM_OUTPUT_ACTIVE_HIGH:
@@ -423,7 +409,7 @@ void pwm_lld_start(PWMDriver *pwmp) {
default:
;
}
- switch (pwmp->pd_config->pc_channels[3].pcc_mode) {
+ switch (pwmp->config->channels[3].mode & PWM_OUTPUT_MASK) {
case PWM_OUTPUT_ACTIVE_LOW:
ccer |= TIM_CCER_CC4P;
case PWM_OUTPUT_ACTIVE_HIGH:
@@ -431,13 +417,46 @@ void pwm_lld_start(PWMDriver *pwmp) {
default:
;
}
- pwmp->pd_tim->CCER = ccer;
- pwmp->pd_tim->EGR = TIM_EGR_UG; /* Update event. */
- pwmp->pd_tim->SR = 0; /* Clear pending IRQs. */
- pwmp->pd_tim->DIER = pwmp->pd_config->pc_callback == NULL ? 0 : TIM_DIER_UIE;
- pwmp->pd_tim->BDTR = TIM_BDTR_MOE;
+#if STM32_PWM_USE_ADVANCED
+ if (&PWMD1 == pwmp) {
+ switch (pwmp->config->channels[0].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
+ ccer |= TIM_CCER_CC1NP;
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
+ ccer |= TIM_CCER_CC1NE;
+ default:
+ ;
+ }
+ switch (pwmp->config->channels[1].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
+ ccer |= TIM_CCER_CC2NP;
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
+ ccer |= TIM_CCER_CC2NE;
+ default:
+ ;
+ }
+ switch (pwmp->config->channels[2].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
+ ccer |= TIM_CCER_CC3NP;
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
+ ccer |= TIM_CCER_CC3NE;
+ default:
+ ;
+ }
+ }
+#endif /* STM32_PWM_USE_ADVANCED*/
+
+ pwmp->tim->CCER = ccer;
+ pwmp->tim->EGR = TIM_EGR_UG; /* Update event. */
+ pwmp->tim->DIER = pwmp->config->callback == NULL ? 0 : TIM_DIER_UIE;
+ pwmp->tim->SR = 0; /* Clear pending IRQs. */
+#if STM32_PWM_USE_ADVANCED
+ pwmp->tim->BDTR = pwmp->config->bdtr | TIM_BDTR_MOE;
+#else
+ pwmp->tim->BDTR = TIM_BDTR_MOE;
+#endif
/* Timer configured and started.*/
- pwmp->pd_tim->CR1 = TIM_CR1_ARPE | TIM_CR1_URS | TIM_CR1_CEN;
+ pwmp->tim->CR1 = TIM_CR1_ARPE | TIM_CR1_URS | TIM_CR1_CEN;
}
/**
@@ -448,20 +467,13 @@ void pwm_lld_start(PWMDriver *pwmp) {
* @notapi
*/
void pwm_lld_stop(PWMDriver *pwmp) {
+
/* If in ready state then disables the PWM clock.*/
- if (pwmp->pd_state == PWM_READY) {
- pwmp->pd_enabled_channels = 0; /* All channels disabled. */
- pwmp->pd_tim->CR1 = 0;
- pwmp->pd_tim->CR2 = 0;
- pwmp->pd_tim->CCER = 0; /* Outputs disabled. */
- pwmp->pd_tim->CCR1 = 0; /* Comparator 1 disabled. */
- pwmp->pd_tim->CCR2 = 0; /* Comparator 2 disabled. */
- pwmp->pd_tim->CCR3 = 0; /* Comparator 3 disabled. */
- pwmp->pd_tim->CCR4 = 0; /* Comparator 4 disabled. */
- pwmp->pd_tim->BDTR = 0;
- pwmp->pd_tim->DIER = 0;
- pwmp->pd_tim->SR = 0;
- pwmp->pd_tim->EGR = TIM_EGR_UG; /* Update event. */
+ if (pwmp->state == PWM_READY) {
+ pwmp->tim->CR1 = 0; /* Timer disabled. */
+ pwmp->tim->DIER = 0; /* All IRQs disabled. */
+ pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */
+ pwmp->tim->BDTR = 0;
#if STM32_PWM_USE_TIM1
if (&PWMD1 == pwmp) {
@@ -499,6 +511,9 @@ void pwm_lld_stop(PWMDriver *pwmp) {
/**
* @brief Enables a PWM channel.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is active using the specified configuration.
+ * @note The function has effect at the next cycle start.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
@@ -510,23 +525,26 @@ void pwm_lld_enable_channel(PWMDriver *pwmp,
pwmchannel_t channel,
pwmcnt_t width) {
- *(&pwmp->pd_tim->CCR1 + (channel * 2)) = width; /* New duty cycle. */
- if ((pwmp->pd_enabled_channels & (1 << channel)) == 0) {
- /* The channel is not enabled yet.*/
- pwmp->pd_enabled_channels |= (1 << channel);
- /* If there is a callback associated to the channel then the proper
- interrupt is cleared and enabled.*/
- if (pwmp->pd_config->pc_channels[channel].pcc_callback) {
- pwmp->pd_tim->SR = ~(2 << channel);
- pwmp->pd_tim->DIER |= (2 << channel);
+ *(&pwmp->tim->CCR1 + (channel * 2)) = width; /* New duty cycle. */
+ /* If there is a callback defined for the channel then the associated
+ interrupt must be enabled.*/
+ if (pwmp->config->channels[channel].callback != NULL) {
+ uint32_t dier = pwmp->tim->DIER;
+ /* If the IRQ is not already enabled care must be taken to clear it,
+ it is probably already pending because the timer is running.*/
+ if ((dier & (2 << channel)) == 0) {
+ pwmp->tim->DIER = dier | (2 << channel);
+ pwmp->tim->SR = ~(2 << channel);
}
}
}
/**
* @brief Disables a PWM channel.
- * @details The channel is disabled and its output line returned to the
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is disabled and its output line returned to the
* idle state.
+ * @note The function has effect at the next cycle start.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
@@ -535,9 +553,8 @@ void pwm_lld_enable_channel(PWMDriver *pwmp,
*/
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
- *(&pwmp->pd_tim->CCR1 + (channel * 2)) = 0;
- pwmp->pd_tim->DIER &= ~(2 << channel);
- pwmp->pd_enabled_channels &= ~(1 << channel);
+ *(&pwmp->tim->CCR1 + (channel * 2)) = 0;
+ pwmp->tim->DIER &= ~(2 << channel);
}
#endif /* HAL_USE_PWM */
diff --git a/os/hal/platforms/STM32/pwm_lld.h b/os/hal/platforms/STM32/pwm_lld.h
index 1e9dd855a..2b3ce7183 100644
--- a/os/hal/platforms/STM32/pwm_lld.h
+++ b/os/hal/platforms/STM32/pwm_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -37,15 +38,55 @@
/**
* @brief Number of PWM channels per PWM driver.
*/
-#define PWM_CHANNELS 4
+#define PWM_CHANNELS 4
+
+/**
+ * @brief Complementary output modes mask.
+ * @note This is an STM32-specific setting.
+ */
+#define PWM_COMPLEMENTARY_OUTPUT_MASK 0xF0
+
+/**
+ * @brief Complementary output not driven.
+ * @note This is an STM32-specific setting.
+ */
+#define PWM_COMPLEMENTARY_OUTPUT_DISABLED 0x00
+
+/**
+ * @brief Complementary output, active is logic level one.
+ * @note This is an STM32-specific setting.
+ * @note This setting is only available if the configuration option
+ * @p STM32_PWM_USE_ADVANCED is set to TRUE and only for advanced
+ * timers TIM1 and TIM8.
+ */
+#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH 0x10
+
+/**
+ * @brief Complementary output, active is logic level zero.
+ * @note This is an STM32-specific setting.
+ * @note This setting is only available if the configuration option
+ * @p STM32_PWM_USE_ADVANCED is set to TRUE and only for advanced
+ * timers TIM1 and TIM8.
+ */
+#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW 0x20
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
- * @brief PWM1 driver enable switch.
- * @details If set to @p TRUE the support for PWM1 is included.
+ * @brief If advanced timer features switch.
+ * @details If set to @p TRUE the advanced features for TIM1 and TIM8 are
+ * enabled.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_PWM_USE_ADVANCED) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_ADVANCED TRUE
+#endif
+
+/**
+ * @brief PWMD1 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD1 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM1) || defined(__DOXYGEN__)
@@ -53,8 +94,8 @@
#endif
/**
- * @brief PWM2 driver enable switch.
- * @details If set to @p TRUE the support for PWM2 is included.
+ * @brief PWMD2 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD2 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM2) || defined(__DOXYGEN__)
@@ -62,8 +103,8 @@
#endif
/**
- * @brief PWM3 driver enable switch.
- * @details If set to @p TRUE the support for PWM3 is included.
+ * @brief PWMD3 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD3 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM3) || defined(__DOXYGEN__)
@@ -71,8 +112,8 @@
#endif
/**
- * @brief PWM4 driver enable switch.
- * @details If set to @p TRUE the support for PWM4 is included.
+ * @brief PWMD4 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD4 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM4) || defined(__DOXYGEN__)
@@ -80,8 +121,8 @@
#endif
/**
- * @brief PWM5 driver enable switch.
- * @details If set to @p TRUE the support for PWM5 is included.
+ * @brief PWMD5 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD5 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_PWM_USE_TIM5) || defined(__DOXYGEN__)
@@ -89,35 +130,35 @@
#endif
/**
- * @brief PWM1 interrupt priority level setting.
+ * @brief PWMD1 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM1_IRQ_PRIORITY 7
#endif
/**
- * @brief PWM2 interrupt priority level setting.
+ * @brief PWMD2 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM2_IRQ_PRIORITY 7
#endif
/**
- * @brief PWM3 interrupt priority level setting.
+ * @brief PWMD3 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM3_IRQ_PRIORITY 7
#endif
/**
- * @brief PWM4 interrupt priority level setting.
+ * @brief PWMD4 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM4_IRQ_PRIORITY 7
#endif
/**
- * @brief PWM5 interrupt priority level setting.
+ * @brief PWMD5 interrupt priority level setting.
*/
#if !defined(STM32_PWM_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_PWM_TIM5_IRQ_PRIORITY 7
@@ -153,11 +194,20 @@
#error "PWM driver activated but no TIM peripheral assigned"
#endif
+#if STM32_PWM_USE_ADVANCED && !STM32_PWM_USE_TIM1
+#error "advanced mode selected but no advanced timer assigned"
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
+ * @brief PWM mode type.
+ */
+typedef uint32_t pwmmode_t;
+
+/**
* @brief PWM channel type.
*/
typedef uint8_t pwmchannel_t;
@@ -168,31 +218,19 @@ typedef uint8_t pwmchannel_t;
typedef uint16_t pwmcnt_t;
/**
- * @brief Type of a structure representing an PWM driver.
- */
-typedef struct PWMDriver PWMDriver;
-
-/**
- * @brief PWM notification callback type.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- */
-typedef void (*pwmcallback_t)(PWMDriver *pwmp);
-
-/**
* @brief PWM driver channel configuration structure.
*/
typedef struct {
/**
* @brief Channel active logic level.
*/
- pwmmode_t pcc_mode;
+ pwmmode_t mode;
/**
* @brief Channel callback pointer.
* @note This callback is invoked on the channel compare event. If set to
* @p NULL then the callback is disabled.
*/
- pwmcallback_t pcc_callback;
+ pwmcallback_t callback;
/* End of the mandatory fields.*/
} PWMChannelConfig;
@@ -201,29 +239,40 @@ typedef struct {
*/
typedef struct {
/**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ uint32_t frequency;
+ /**
+ * @brief PWM period in ticks.
+ * @note The low level can use assertions in order to catch invalid
+ * period specifications.
+ */
+ pwmcnt_t period;
+ /**
* @brief Periodic callback pointer.
* @note This callback is invoked on PWM counter reset. If set to
* @p NULL then the callback is disabled.
*/
- pwmcallback_t pc_callback;
+ pwmcallback_t callback;
/**
* @brief Channels configurations.
*/
- PWMChannelConfig pc_channels[PWM_CHANNELS];
+ PWMChannelConfig channels[PWM_CHANNELS];
/* End of the mandatory fields.*/
/**
- * @brief TIM PSC (pre-scaler) register initialization data.
- */
- uint16_t pc_psc;
- /**
- * @brief TIM ARR (auto-reload) register initialization data.
- */
- uint16_t pc_arr;
- /**
* @brief TIM CR2 register initialization data.
* @note The value of this field should normally be equal to zero.
*/
- uint16_t pc_cr2;
+ uint16_t cr2;
+#if STM32_PWM_USE_ADVANCED || defined(__DOXYGEN__)
+ /**
+ * @brief TIM BDTR (break & dead-time) register initialization data.
+ * @note The value of this field should normally be equal to zero.
+ */ \
+ uint16_t bdtr;
+#endif
} PWMConfig;
/**
@@ -233,23 +282,23 @@ struct PWMDriver {
/**
* @brief Driver state.
*/
- pwmstate_t pd_state;
+ pwmstate_t state;
/**
* @brief Current driver configuration data.
*/
- const PWMConfig *pd_config;
+ const PWMConfig *config;
+ /**
+ * @brief Current PWM period in ticks.
+ */
+ pwmcnt_t period;
#if defined(PWM_DRIVER_EXT_FIELDS)
PWM_DRIVER_EXT_FIELDS
#endif
/* End of the mandatory fields.*/
/**
- * @brief Bit mask of the enabled channels.
- */
- uint32_t pd_enabled_channels;
- /**
* @brief Pointer to the TIMx registers block.
*/
- TIM_TypeDef *pd_tim;
+ TIM_TypeDef *tim;
};
/*===========================================================================*/
@@ -257,88 +306,23 @@ struct PWMDriver {
/*===========================================================================*/
/**
- * @brief PWM clock prescaler initialization utility.
- * @note The real clock value is rounded to the lower valid value, please
- * make sure that the source clock frequency is a multiple of the
- * requested PWM clock frequency.
- * @note The calculated value must fit into an unsigned 16 bits integer.
- *
- * @param[in] clksrc clock source frequency, depending on the target timer
- * cell it can be one of:
- * - STM32_TIMCLK1
- * - STM32_TIMCLK2
- * .
- * Please refer to the STM32 HAL driver documentation
- * and/or the STM32 Reference Manual for the right clock
- * source.
- * @param[in] pwmclk PWM clock frequency in cycles
- * @return The value to be stored in the @p pc_psc field of the
- * @p PWMConfig structure.
- */
-#define PWM_COMPUTE_PSC(clksrc, pwmclk) \
- ((uint16_t)(((clksrc) / (pwmclk)) - 1))
-
-/**
- * @brief PWM cycle period initialization utility.
- * @note The calculated value must fit into an unsigned 16 bits integer.
- *
- * @param[in] pwmclk PWM clock frequency in cycles
- * @param[in] pwmperiod PWM cycle period in nanoseconds
- * @return The value to be stored in the @p pc_arr field of the
- * @p PWMConfig structure.
- */
-#define PWM_COMPUTE_ARR(pwmclk, pwmperiod) \
- ((uint16_t)(((pwmclk) / (1000000000 / (pwmperiod))) - 1))
-
-/**
- * @brief Converts from fraction to pulse width.
- * @note Be careful with rounding errors, this is integer math not magic.
- * You can specify tenths of thousandth but make sure you have the
- * proper hardware resolution by carefully choosing the clock source
- * and prescaler settings, see @p PWM_COMPUTE_PSC.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] numerator numerator of the fraction
- * @param[in] denominator percentage as an integer between 0 and numerator
- * @return The pulse width to be passed to @p pwmEnableChannel().
- *
- * @api
- */
-#define PWM_FRACTION_TO_WIDTH(pwmp, numerator, denominator) \
- ((uint16_t)((((uint32_t)(pwmp)->pd_config->pc_arr + 1UL) * \
- (uint32_t)(denominator)) / (uint32_t)(numerator)))
-
-/**
- * @brief Converts from degrees to pulse width.
- * @note Be careful with rounding errors, this is integer math not magic.
- * You can specify hundredths of degrees but make sure you have the
- * proper hardware resolution by carefully choosing the clock source
- * and prescaler settings, see @p PWM_COMPUTE_PSC.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] degrees degrees as an integer between 0 and 36000
- * @return The pulse width to be passed to @p pwmEnableChannel().
- *
- * @api
- */
-#define PWM_DEGREES_TO_WIDTH(pwmp, degrees) \
- PWM_FRACTION_TO_WIDTH(pwmp, 36000, degrees)
-
-/**
- * @brief Converts from percentage to pulse width.
- * @note Be careful with rounding errors, this is integer math not magic.
- * You can specify tenths of thousandth but make sure you have the
- * proper hardware resolution by carefully choosing the clock source
- * and prescaler settings, see @p PWM_COMPUTE_PSC.
+ * @brief Changes the period the PWM peripheral.
+ * @details This function changes the period of a PWM unit that has already
+ * been activated using @p pwmStart().
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The PWM unit period is changed to the new value.
+ * @note The function has effect at the next cycle start.
+ * @note If a period is specified that is shorter than the pulse width
+ * programmed in one of the channels then the behavior is not
+ * guaranteed.
*
* @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] percentage percentage as an integer between 0 and 10000
- * @return The pulse width to be passed to @p pwmEnableChannel().
+ * @param[in] period new cycle time in ticks
*
- * @api
+ * @notapi
*/
-#define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \
- PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage)
+#define pwm_lld_change_period(pwmp, period) \
+ ((pwmp)->tim->ARR = (uint16_t)((period) - 1))
/*===========================================================================*/
/* External declarations. */
diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c
new file mode 100644
index 000000000..a88ad53fa
--- /dev/null
+++ b/os/hal/platforms/STM32/sdc_lld.c
@@ -0,0 +1,722 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/sdc_lld.c
+ * @brief STM32 SDC subsystem low level driver source.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#include <string.h>
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief SDCD1 driver identifier.*/
+SDCDriver SDCD1;
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+#if STM32_SDC_UNALIGNED_SUPPORT
+/**
+ * @brief Buffer for temporary storage during unaligned transfers.
+ */
+static union {
+ uint32_t alignment;
+ uint8_t buf[SDC_BLOCK_SIZE];
+} u;
+#endif
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Reads one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer, it must be aligned to
+ * four bytes boundary
+ * @param[in] n number of blocks to read
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * read.
+ * @retval TRUE operation failed, the state of the buffer is uncertain.
+ *
+ * @notapi
+ */
+static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t n) {
+ uint32_t resp[1];
+
+ /* Checks for errors and waits for the card to be ready for reading.*/
+ if (sdc_wait_for_transfer_state(sdcp))
+ return TRUE;
+
+ /* Prepares the DMA channel for reading.*/
+ dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
+ (n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf,
+ (STM32_SDC_SDIO_DMA_PRIORITY << 12) |
+ DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
+ DMA_CCR1_MINC);
+
+ /* Setting up data transfer.
+ Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE |
+ SDIO_MASK_DATAENDIE | SDIO_MASK_STBITERRIE;
+ SDIO->DLEN = n * SDC_BLOCK_SIZE;
+ SDIO->DCTRL = SDIO_DCTRL_DTDIR |
+ SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
+ SDIO_DCTRL_DMAEN |
+ SDIO_DCTRL_DTEN;
+
+ /* DMA channel activation.*/
+ dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+
+ /* Read multiple blocks command.*/
+ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
+ startblk *= SDC_BLOCK_SIZE;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK,
+ startblk, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto error;
+
+ chSysLock();
+ if (SDIO->MASK != 0) {
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_read_multiple(), #1", "not NULL");
+ sdcp->thread = chThdSelf();
+ chSchGoSleepS(THD_STATE_SUSPENDED);
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_read_multiple(), #2", "not NULL");
+ }
+ if ((SDIO->STA & SDIO_STA_DATAEND) == 0) {
+ chSysUnlock();
+ goto error;
+ }
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->DCTRL = 0;
+ chSysUnlock();
+
+ return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp);
+error:
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = 0;
+ SDIO->DCTRL = 0;
+ return TRUE;
+}
+
+/**
+ * @brief Reads one block.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer, it must be aligned to
+ * four bytes boundary
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * read.
+ * @retval TRUE operation failed, the state of the buffer is uncertain.
+ *
+ * @notapi
+ */
+static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf) {
+ uint32_t resp[1];
+
+ /* Checks for errors and waits for the card to be ready for reading.*/
+ if (sdc_wait_for_transfer_state(sdcp))
+ return TRUE;
+
+ /* Prepares the DMA channel for reading.*/
+ dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
+ SDC_BLOCK_SIZE / sizeof (uint32_t), buf,
+ (STM32_SDC_SDIO_DMA_PRIORITY << 12) |
+ DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
+ DMA_CCR1_MINC);
+
+ /* Setting up data transfer.
+ Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE |
+ SDIO_MASK_DATAENDIE | SDIO_MASK_STBITERRIE;
+ SDIO->DLEN = SDC_BLOCK_SIZE;
+ SDIO->DCTRL = SDIO_DCTRL_DTDIR |
+ SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
+ SDIO_DCTRL_DMAEN |
+ SDIO_DCTRL_DTEN;
+
+ /* DMA channel activation.*/
+ dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+
+ /* Read single block command.*/
+ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
+ startblk *= SDC_BLOCK_SIZE;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_SINGLE_BLOCK,
+ startblk, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto error;
+
+ chSysLock();
+ if (SDIO->MASK != 0) {
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_read_single(), #1", "not NULL");
+ sdcp->thread = chThdSelf();
+ chSchGoSleepS(THD_STATE_SUSPENDED);
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_read_single(), #2", "not NULL");
+ }
+ if ((SDIO->STA & SDIO_STA_DATAEND) == 0) {
+ chSysUnlock();
+ goto error;
+ }
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->DCTRL = 0;
+ chSysUnlock();
+
+ return FALSE;
+error:
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = 0;
+ SDIO->DCTRL = 0;
+ return TRUE;
+}
+
+/**
+ * @brief Writes one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer, it must be aligned to
+ * four bytes boundary
+ * @param[in] n number of blocks to write
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * written.
+ * @retval TRUE operation failed.
+ *
+ * @notapi
+ */
+static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t n) {
+ uint32_t resp[1];
+
+ /* Checks for errors and waits for the card to be ready for writing.*/
+ if (sdc_wait_for_transfer_state(sdcp))
+ return TRUE;
+
+ /* Prepares the DMA channel for writing.*/
+ dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
+ (n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf,
+ (STM32_SDC_SDIO_DMA_PRIORITY << 12) |
+ DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
+ DMA_CCR1_MINC | DMA_CCR1_DIR);
+
+ /* Write multiple blocks command.*/
+ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
+ startblk *= SDC_BLOCK_SIZE;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_MULTIPLE_BLOCK,
+ startblk, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ return TRUE;
+
+ /* Setting up data transfer.
+ Options: Controller to Card, Block mode, DMA mode, 512 bytes blocks.*/
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE |
+ SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE |
+ SDIO_MASK_STBITERRIE;
+ SDIO->DLEN = n * SDC_BLOCK_SIZE;
+ SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
+ SDIO_DCTRL_DMAEN |
+ SDIO_DCTRL_DTEN;
+
+ /* DMA channel activation.*/
+ dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+
+ /* Note the mask is checked before going to sleep because the interrupt
+ may have occurred before reaching the critical zone.*/
+ chSysLock();
+ if (SDIO->MASK != 0) {
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_write_multiple(), #1", "not NULL");
+ sdcp->thread = chThdSelf();
+ chSchGoSleepS(THD_STATE_SUSPENDED);
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_write_multiple(), #2", "not NULL");
+ }
+ if ((SDIO->STA & SDIO_STA_DATAEND) == 0) {
+ chSysUnlock();
+ goto error;
+ }
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->DCTRL = 0;
+ chSysUnlock();
+
+ return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp);
+error:
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = 0;
+ SDIO->DCTRL = 0;
+ return TRUE;
+}
+
+/**
+ * @brief Writes one block.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer, it must be aligned to
+ * four bytes boundary
+ * @param[in] n number of blocks to write
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * written.
+ * @retval TRUE operation failed.
+ *
+ * @notapi
+ */
+static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf) {
+ uint32_t resp[1];
+
+ /* Checks for errors and waits for the card to be ready for writing.*/
+ if (sdc_wait_for_transfer_state(sdcp))
+ return TRUE;
+
+ /* Prepares the DMA channel for writing.*/
+ dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
+ SDC_BLOCK_SIZE / sizeof (uint32_t), buf,
+ (STM32_SDC_SDIO_DMA_PRIORITY << 12) |
+ DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
+ DMA_CCR1_MINC | DMA_CCR1_DIR);
+
+ /* Write single block command.*/
+ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
+ startblk *= SDC_BLOCK_SIZE;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_BLOCK,
+ startblk, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ return TRUE;
+
+ /* Setting up data transfer.
+ Options: Controller to Card, Block mode, DMA mode, 512 bytes blocks.*/
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE |
+ SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE |
+ SDIO_MASK_STBITERRIE;
+ SDIO->DLEN = SDC_BLOCK_SIZE;
+ SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
+ SDIO_DCTRL_DMAEN |
+ SDIO_DCTRL_DTEN;
+
+ /* DMA channel activation.*/
+ dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+
+ /* Note the mask is checked before going to sleep because the interrupt
+ may have occurred before reaching the critical zone.*/
+ chSysLock();
+ if (SDIO->MASK != 0) {
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_write_single(), #1", "not NULL");
+ sdcp->thread = chThdSelf();
+ chSchGoSleepS(THD_STATE_SUSPENDED);
+ chDbgAssert(sdcp->thread == NULL,
+ "sdc_lld_write_single(), #2", "not NULL");
+ }
+ if ((SDIO->STA & SDIO_STA_DATAEND) == 0) {
+ chSysUnlock();
+ goto error;
+ }
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->DCTRL = 0;
+ chSysUnlock();
+
+ return FALSE;
+error:
+ dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ SDIO->ICR = 0xFFFFFFFF;
+ SDIO->MASK = 0;
+ SDIO->DCTRL = 0;
+ return TRUE;
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/**
+ * @brief SDIO IRQ handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SDIO_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ chSysLockFromIsr();
+ if (SDCD1.thread != NULL) {
+ chSchReadyI(SDCD1.thread);
+ SDCD1.thread = NULL;
+ }
+ chSysUnlockFromIsr();
+
+ /* Disables the source but the status flags are not reset because the
+ read/write functions need to check them.*/
+ SDIO->MASK = 0;
+
+ CH_IRQ_EPILOGUE();
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level SDC driver initialization.
+ *
+ * @notapi
+ */
+void sdc_lld_init(void) {
+
+ sdcObjectInit(&SDCD1);
+ SDCD1.thread = NULL;
+}
+
+/**
+ * @brief Configures and activates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object, must be @p NULL,
+ * this driver does not require any configuration
+ *
+ * @notapi
+ */
+void sdc_lld_start(SDCDriver *sdcp) {
+
+ if (sdcp->state == SDC_STOP) {
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_4, NULL, NULL);
+ dmaChannelSetPeripheral(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], &SDIO->FIFO);
+ NVICEnableVector(SDIO_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_SDC_SDIO_IRQ_PRIORITY));
+ RCC->AHBENR |= RCC_AHBENR_SDIOEN;
+ }
+ /* Configuration, card clock is initially stopped.*/
+ SDIO->POWER = 0;
+ SDIO->CLKCR = 0;
+ SDIO->DCTRL = 0;
+ SDIO->DTIMER = STM32_SDC_DATATIMEOUT;
+}
+
+/**
+ * @brief Deactivates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_stop(SDCDriver *sdcp) {
+
+ if ((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE)) {
+ SDIO->POWER = 0;
+ SDIO->CLKCR = 0;
+ SDIO->DCTRL = 0;
+ SDIO->DTIMER = 0;
+
+ /* Clock deactivation.*/
+ NVICDisableVector(SDIO_IRQn);
+ dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_4);
+ }
+}
+
+/**
+ * @brief Starts the SDIO clock and sets it to init mode (400KHz or less).
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_start_clk(SDCDriver *sdcp) {
+
+ (void)sdcp;
+ /* 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;
+}
+
+/**
+ * @brief Sets the SDIO clock to data mode (25MHz or less).
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_set_data_clk(SDCDriver *sdcp) {
+
+ (void)sdcp;
+ SDIO->CLKCR = (SDIO->CLKCR & 0xFFFFFF00) | STM32_SDIO_DIV_HS;
+}
+
+/**
+ * @brief Stops the SDIO clock.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_stop_clk(SDCDriver *sdcp) {
+
+ (void)sdcp;
+ SDIO->CLKCR = 0;
+ SDIO->POWER = 0;
+}
+
+/**
+ * @brief Switches the bus to 4 bits mode.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] mode bus mode
+ *
+ * @notapi
+ */
+void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) {
+ uint32_t clk = SDIO->CLKCR & ~SDIO_CLKCR_WIDBUS;
+
+ (void)sdcp;
+ switch (mode) {
+ case SDC_MODE_1BIT:
+ SDIO->CLKCR = clk;
+ break;
+ case SDC_MODE_4BIT:
+ SDIO->CLKCR = clk | SDIO_CLKCR_WIDBUS_0;
+ break;
+ case SDC_MODE_8BIT:
+ SDIO->CLKCR = clk | SDIO_CLKCR_WIDBUS_1;
+ }
+}
+
+/**
+ * @brief Sends an SDIO command with no response expected.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ *
+ * @notapi
+ */
+void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) {
+
+ (void)sdcp;
+ SDIO->ARG = arg;
+ SDIO->CMD = (uint32_t)cmd | SDIO_CMD_CPSMEN;
+ while ((SDIO->STA & SDIO_STA_CMDSENT) == 0)
+ ;
+ SDIO->ICR = SDIO_ICR_CMDSENTC;
+}
+
+/**
+ * @brief Sends an SDIO command with a short response expected.
+ * @note The CRC is not verified.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (one word)
+ * @return The operation status.
+ * @retval FALSE the operation succeeded.
+ * @retval TRUE the operation failed because timeout, CRC check or
+ * other errors.
+ *
+ * @notapi
+ */
+bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+ uint32_t sta;
+
+ (void)sdcp;
+ SDIO->ARG = arg;
+ SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN;
+ while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
+ SDIO_STA_CCRCFAIL)) == 0)
+ ;
+ SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
+ if ((sta & (SDIO_STA_CTIMEOUT)) != 0)
+ return TRUE;
+ *resp = SDIO->RESP1;
+ return FALSE;
+}
+
+/**
+ * @brief Sends an SDIO command with a short response expected and CRC.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (one word)
+ * @return The operation status.
+ * @retval FALSE the operation succeeded.
+ * @retval TRUE the operation failed because timeout, CRC check or
+ * other errors.
+ *
+ * @notapi
+ */
+bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+ uint32_t sta;
+
+ (void)sdcp;
+ SDIO->ARG = arg;
+ SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN;
+ while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
+ SDIO_STA_CCRCFAIL)) == 0)
+ ;
+ SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
+ if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0)
+ return TRUE;
+ *resp = SDIO->RESP1;
+ return FALSE;
+}
+
+/**
+ * @brief Sends an SDIO command with a long response expected and CRC.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (four words)
+ * @return The operation status.
+ * @retval FALSE the operation succeeded.
+ * @retval TRUE the operation failed because timeout, CRC check or
+ * other errors.
+ *
+ * @notapi
+ */
+bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+
+ uint32_t sta;
+
+ (void)sdcp;
+ SDIO->ARG = arg;
+ SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_WAITRESP_1 |
+ SDIO_CMD_CPSMEN;
+ while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
+ SDIO_STA_CCRCFAIL)) == 0)
+ ;
+ SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
+ if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0)
+ return TRUE;
+ *resp = SDIO->RESP1;
+ return FALSE;
+}
+
+/**
+ * @brief Reads one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer
+ * @param[in] n number of blocks to read
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * read.
+ * @retval TRUE operation failed, the state of the buffer is uncertain.
+ *
+ * @notapi
+ */
+bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t n) {
+
+#if STM32_SDC_UNALIGNED_SUPPORT
+ if (((unsigned)buf & 3) != 0) {
+ uint32_t i;
+ for (i = 0; i < n; i++) {
+ if (sdc_lld_read_single(sdcp, startblk, u.buf))
+ return TRUE;
+ memcpy(buf, u.buf, SDC_BLOCK_SIZE);
+ buf += SDC_BLOCK_SIZE;
+ startblk++;
+ }
+ return FALSE;
+ }
+#endif
+ if (n == 1)
+ return sdc_lld_read_single(sdcp, startblk, buf);
+ return sdc_lld_read_multiple(sdcp, startblk, buf, n);
+}
+
+/**
+ * @brief Writes one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer
+ * @param[in] n number of blocks to write
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * written.
+ * @retval TRUE operation failed.
+ *
+ * @notapi
+ */
+bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t n) {
+
+ #if STM32_SDC_UNALIGNED_SUPPORT
+ if (((unsigned)buf & 3) != 0) {
+ uint32_t i;
+ for (i = 0; i < n; i++) {
+ memcpy(u.buf, buf, SDC_BLOCK_SIZE);
+ buf += SDC_BLOCK_SIZE;
+ if (sdc_lld_write_single(sdcp, startblk, u.buf))
+ return TRUE;
+ startblk++;
+ }
+ return FALSE;
+ }
+#endif
+ if (n == 1)
+ return sdc_lld_write_single(sdcp, startblk, buf);
+ return sdc_lld_write_multiple(sdcp, startblk, buf, n);
+}
+
+#endif /* HAL_USE_SDC */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h
new file mode 100644
index 000000000..5466eacad
--- /dev/null
+++ b/os/hal/platforms/STM32/sdc_lld.h
@@ -0,0 +1,203 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/sdc_lld.h
+ * @brief STM32 SDC subsystem low level driver header.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#ifndef _SDC_LLD_H_
+#define _SDC_LLD_H_
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief SDIO data timeout in SDIO clock cycles.
+ */
+#if !defined(STM32_SDC_DATATIMEOUT) || defined(__DOXYGEN__)
+#define STM32_SDC_DATATIMEOUT 0x000FFFFF
+#endif
+
+/**
+ * @brief SDIO DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_SDC_SDIO_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDIO_DMA_PRIORITY 3
+#endif
+
+/**
+ * @brief SDIO interrupt priority level setting.
+ */
+#if !defined(STM32_SDC_SDIO_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDIO_IRQ_PRIORITY 9
+#endif
+
+/**
+ * @brief SDIO support for unaligned transfers.
+ */
+#if !defined(STM32_SDC_UNALIGNED_SUPPORT) || defined(__DOXYGEN__)
+#define STM32_SDC_UNALIGNED_SUPPORT TRUE
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !STM32_HAS_SDIO
+#error "SDIO not present in the selected device"
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*
+ * SDIO clock divider.
+ */
+#if STM32_HCLK > 48000000
+#define STM32_SDIO_DIV_HS 0x01
+#define STM32_SDIO_DIV_LS 0xB2
+#else
+#define STM32_SDIO_DIV_HS 0x00
+#define STM32_SDIO_DIV_LS 0x76
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of SDIO bus mode.
+ */
+typedef enum {
+ SDC_MODE_1BIT = 0,
+ SDC_MODE_4BIT,
+ SDC_MODE_8BIT
+} sdcbusmode_t;
+
+/**
+ * @brief Type of card flags.
+ */
+typedef uint32_t sdcmode_t;
+
+/**
+ * @brief Type of a structure representing an SDC driver.
+ */
+typedef struct SDCDriver SDCDriver;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ uint32_t dummy;
+} SDCConfig;
+
+/**
+ * @brief Structure representing an SDC driver.
+ */
+struct SDCDriver {
+ /**
+ * @brief Driver state.
+ */
+ sdcstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const SDCConfig *config;
+ /**
+ * @brief Various flags regarding the mounted card.
+ */
+ sdcmode_t cardmode;
+ /**
+ * @brief Card CID.
+ */
+ uint32_t cid[4];
+ /**
+ * @brief Card CSD.
+ */
+ uint32_t csd[4];
+ /**
+ * @brief Card RCA.
+ */
+ uint32_t rca;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Tthread waiting for I/O completion IRQ.
+ */
+ Thread *thread;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern SDCDriver SDCD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void sdc_lld_init(void);
+ void sdc_lld_start(SDCDriver *sdcp);
+ void sdc_lld_stop(SDCDriver *sdcp);
+ void sdc_lld_start_clk(SDCDriver *sdcp);
+ void sdc_lld_set_data_clk(SDCDriver *sdcp);
+ void sdc_lld_stop_clk(SDCDriver *sdcp);
+ void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode);
+ void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg);
+ bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t n);
+ bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t n);
+ bool_t sdc_lld_is_card_inserted(SDCDriver *sdcp);
+ bool_t sdc_lld_is_write_protected(SDCDriver *sdcp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SDC */
+
+#endif /* _SDC_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/serial_lld.c b/os/hal/platforms/STM32/serial_lld.c
index b20c2a933..5aaa60de9 100644
--- a/os/hal/platforms/STM32/serial_lld.c
+++ b/os/hal/platforms/STM32/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM32/serial_lld.h b/os/hal/platforms/STM32/serial_lld.h
index d16e1923d..ceeccff67 100644
--- a/os/hal/platforms/STM32/serial_lld.h
+++ b/os/hal/platforms/STM32/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM32/spi_lld.c b/os/hal/platforms/STM32/spi_lld.c
index dfe72822a..d8ae657a7 100644
--- a/os/hal/platforms/STM32/spi_lld.c
+++ b/os/hal/platforms/STM32/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -66,8 +67,8 @@ static uint16_t dummyrx;
* @param[in] spip pointer to the @p SPIDriver object
*/
#define dma_stop(spip) { \
- dmaChannelDisable(spip->spd_dmatx); \
- dmaChannelDisable(spip->spd_dmarx); \
+ dmaChannelDisable(spip->dmatx); \
+ dmaChannelDisable(spip->dmarx); \
}
/**
@@ -76,16 +77,26 @@ static uint16_t dummyrx;
* @param[in] spip pointer to the @p SPIDriver object
*/
#define dma_start(spip) { \
- dmaChannelEnable((spip)->spd_dmarx); \
- dmaChannelEnable((spip)->spd_dmatx); \
+ dmaChannelEnable((spip)->dmarx); \
+ dmaChannelEnable((spip)->dmatx); \
}
/**
- * @brief Shared end-of-transfer service routine.
+ * @brief Shared end-of-rx service routine.
*
* @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-static void serve_interrupt(SPIDriver *spip) {
+static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
+ }
+#else
+ (void)flags;
+#endif
/* Stop everything.*/
dma_stop(spip);
@@ -95,114 +106,29 @@ static void serve_interrupt(SPIDriver *spip) {
_spi_isr_code(spip);
}
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__)
/**
- * @brief SPI1 RX DMA interrupt handler (channel 2).
+ * @brief Shared end-of-tx service routine.
*
- * @isr
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
+static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF2) != 0) {
- STM32_SPI_SPI1_DMA_ERROR_HOOK();
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ (void)spip;
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
}
- serve_interrupt(&SPID1);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief SPI1 TX DMA interrupt handler (channel 3).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- STM32_SPI_SPI1_DMA_ERROR_HOOK();
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
-
- CH_IRQ_EPILOGUE();
-}
+#else
+ (void)spip;
+ (void)flags;
#endif
-
-#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__)
-/**
- * @brief SPI2 RX DMA interrupt handler (channel 4).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF4) != 0) {
- STM32_SPI_SPI2_DMA_ERROR_HOOK();
- }
- serve_interrupt(&SPID2);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
-
- CH_IRQ_EPILOGUE();
}
-/**
- * @brief SPI2 TX DMA interrupt handler (channel 5).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- STM32_SPI_SPI2_DMA_ERROR_HOOK();
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
-
- CH_IRQ_EPILOGUE();
-}
-#endif
-
-#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__)
-/**
- * @brief SPI3 RX DMA interrupt handler (DMA2, channel 1).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA2->ISR & DMA_ISR_TEIF1) != 0) {
- STM32_SPI_SPI3_DMA_ERROR_HOOK();
- }
- serve_interrupt(&SPID3);
- dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief SPI3 TX DMA2 interrupt handler (DMA2, channel 2).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- STM32_SPI_SPI3_DMA_ERROR_HOOK();
- dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_2);
-
- CH_IRQ_EPILOGUE();
-}
-#endif
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
@@ -218,33 +144,27 @@ void spi_lld_init(void) {
dummytx = 0xFFFF;
#if STM32_SPI_USE_SPI1
- RCC->APB2RSTR = RCC_APB2RSTR_SPI1RST;
- RCC->APB2RSTR = 0;
spiObjectInit(&SPID1);
- SPID1.spd_thread = NULL;
- SPID1.spd_spi = SPI1;
- SPID1.spd_dmarx = STM32_DMA1_CH2;
- SPID1.spd_dmatx = STM32_DMA1_CH3;
+ SPID1.thread = NULL;
+ SPID1.spi = SPI1;
+ SPID1.dmarx = STM32_DMA1_CH2;
+ SPID1.dmatx = STM32_DMA1_CH3;
#endif
#if STM32_SPI_USE_SPI2
- RCC->APB1RSTR = RCC_APB1RSTR_SPI2RST;
- RCC->APB1RSTR = 0;
spiObjectInit(&SPID2);
- SPID2.spd_thread = NULL;
- SPID2.spd_spi = SPI2;
- SPID2.spd_dmarx = STM32_DMA1_CH4;
- SPID2.spd_dmatx = STM32_DMA1_CH5;
+ SPID2.thread = NULL;
+ SPID2.spi = SPI2;
+ SPID2.dmarx = STM32_DMA1_CH4;
+ SPID2.dmatx = STM32_DMA1_CH5;
#endif
#if STM32_SPI_USE_SPI3
- RCC->APB1RSTR = RCC_APB1RSTR_SPI3RST;
- RCC->APB1RSTR = 0;
spiObjectInit(&SPID3);
- SPID3.spd_thread = NULL;
- SPID3.spd_spi = SPI3;
- SPID3.spd_dmarx = STM32_DMA2_CH1;
- SPID3.spd_dmatx = STM32_DMA2_CH2;
+ SPID3.thread = NULL;
+ SPID3.spi = SPI3;
+ SPID3.dmarx = STM32_DMA2_CH1;
+ SPID3.dmatx = STM32_DMA2_CH2;
#endif
}
@@ -258,10 +178,14 @@ void spi_lld_init(void) {
void spi_lld_start(SPIDriver *spip) {
/* If in stopped state then enables the SPI and DMA clocks.*/
- if (spip->spd_state == SPI_STOP) {
+ if (spip->state == SPI_STOP) {
#if STM32_SPI_USE_SPI1
if (&SPID1 == spip) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip);
NVICEnableVector(DMA1_Channel2_IRQn,
CORTEX_PRIORITY_MASK(STM32_SPI_SPI1_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel3_IRQn,
@@ -271,7 +195,11 @@ void spi_lld_start(SPIDriver *spip) {
#endif
#if STM32_SPI_USE_SPI2
if (&SPID2 == spip) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip);
NVICEnableVector(DMA1_Channel4_IRQn,
CORTEX_PRIORITY_MASK(STM32_SPI_SPI2_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel5_IRQn,
@@ -281,7 +209,11 @@ void spi_lld_start(SPIDriver *spip) {
#endif
#if STM32_SPI_USE_SPI3
if (&SPID3 == spip) {
- dmaEnable(DMA2_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_1,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip);
+ dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_2,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip);
NVICEnableVector(DMA2_Channel1_IRQn,
CORTEX_PRIORITY_MASK(STM32_SPI_SPI3_IRQ_PRIORITY));
NVICEnableVector(DMA2_Channel2_IRQn,
@@ -291,23 +223,25 @@ void spi_lld_start(SPIDriver *spip) {
#endif
/* DMA setup.*/
- dmaChannelSetPeripheral(spip->spd_dmarx, &spip->spd_spi->DR);
- dmaChannelSetPeripheral(spip->spd_dmatx, &spip->spd_spi->DR);
+ dmaChannelSetPeripheral(spip->dmarx, &spip->spi->DR);
+ dmaChannelSetPeripheral(spip->dmatx, &spip->spi->DR);
}
/* More DMA setup.*/
- if ((spip->spd_config->spc_cr1 & SPI_CR1_DFF) == 0)
- spip->spd_dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) |
- DMA_CCR1_TEIE; /* 8 bits transfers. */
+ if ((spip->config->cr1 & SPI_CR1_DFF) == 0)
+ spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) |
+ DMA_CCR1_TEIE; /* 8 bits transfers. */
else
- spip->spd_dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) |
- DMA_CCR1_TEIE | DMA_CCR1_MSIZE_0 |
- DMA_CCR1_PSIZE_0; /* 16 bits transfers. */
+ spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) |
+ DMA_CCR1_TEIE | DMA_CCR1_MSIZE_0 |
+ DMA_CCR1_PSIZE_0; /* 16 bits transfers. */
/* SPI setup and enable.*/
- spip->spd_spi->CR1 = 0;
- spip->spd_spi->CR2 = SPI_CR2_SSOE | SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN;
- spip->spd_spi->CR1 = spip->spd_config->spc_cr1 | SPI_CR1_MSTR | SPI_CR1_SPE;
+ spip->spi->CR1 = 0;
+ spip->spi->CR1 = spip->config->cr1 | SPI_CR1_MSTR | SPI_CR1_SSM |
+ SPI_CR1_SSI;
+ spip->spi->CR2 = SPI_CR2_SSOE | SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN;
+ spip->spi->CR1 |= SPI_CR1_SPE;
}
/**
@@ -320,16 +254,17 @@ void spi_lld_start(SPIDriver *spip) {
void spi_lld_stop(SPIDriver *spip) {
/* If in ready state then disables the SPI clock.*/
- if (spip->spd_state == SPI_READY) {
+ if (spip->state == SPI_READY) {
/* SPI disable.*/
- spip->spd_spi->CR1 = 0;
+ spip->spi->CR1 = 0;
#if STM32_SPI_USE_SPI1
if (&SPID1 == spip) {
NVICDisableVector(DMA1_Channel2_IRQn);
NVICDisableVector(DMA1_Channel3_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3);
RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN;
}
#endif
@@ -337,7 +272,8 @@ void spi_lld_stop(SPIDriver *spip) {
if (&SPID2 == spip) {
NVICDisableVector(DMA1_Channel4_IRQn);
NVICDisableVector(DMA1_Channel5_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5);
RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN;
}
#endif
@@ -345,7 +281,8 @@ void spi_lld_stop(SPIDriver *spip) {
if (&SPID3 == spip) {
NVICDisableVector(DMA2_Channel1_IRQn);
NVICDisableVector(DMA2_Channel2_IRQn);
- dmaDisable(DMA2_ID);
+ dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_1);
+ dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_2);
RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN;
}
#endif
@@ -361,7 +298,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
- palClearPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -374,7 +311,7 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
- palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -390,10 +327,10 @@ void spi_lld_unselect(SPIDriver *spip) {
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
- dmaChannelSetup(spip->spd_dmarx, n, &dummyrx,
- spip->spd_dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN);
- dmaChannelSetup(spip->spd_dmatx, n, &dummytx,
- spip->spd_dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN);
+ dmaChannelSetup(spip->dmarx, n, &dummyrx,
+ spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN);
+ dmaChannelSetup(spip->dmatx, n, &dummytx,
+ spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN);
}
/**
@@ -414,11 +351,11 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
- dmaChannelSetup(spip->spd_dmarx, n, rxbuf,
- spip->spd_dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC |
+ dmaChannelSetup(spip->dmarx, n, rxbuf,
+ spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC |
DMA_CCR1_EN);
- dmaChannelSetup(spip->spd_dmatx, n, txbuf,
- spip->spd_dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
+ dmaChannelSetup(spip->dmatx, n, txbuf,
+ spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
DMA_CCR1_EN);
}
@@ -437,10 +374,10 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
- dmaChannelSetup(spip->spd_dmarx, n, &dummyrx,
- spip->spd_dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN);
- dmaChannelSetup(spip->spd_dmatx, n, txbuf,
- spip->spd_dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
+ dmaChannelSetup(spip->dmarx, n, &dummyrx,
+ spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN);
+ dmaChannelSetup(spip->dmatx, n, txbuf,
+ spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
DMA_CCR1_EN);
}
@@ -459,11 +396,11 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
- dmaChannelSetup(spip->spd_dmarx, n, rxbuf,
- spip->spd_dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC |
+ dmaChannelSetup(spip->dmarx, n, rxbuf,
+ spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC |
DMA_CCR1_EN);
- dmaChannelSetup(spip->spd_dmatx, n, &dummytx,
- spip->spd_dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN);
+ dmaChannelSetup(spip->dmatx, n, &dummytx,
+ spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN);
}
/**
@@ -480,10 +417,10 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
*/
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
- spip->spd_spi->DR = frame;
- while ((spip->spd_spi->SR & SPI_SR_RXNE) == 0)
+ spip->spi->DR = frame;
+ while ((spip->spi->SR & SPI_SR_RXNE) == 0)
;
- return spip->spd_spi->DR;
+ return spip->spi->DR;
}
#endif /* HAL_USE_SPI */
diff --git a/os/hal/platforms/STM32/spi_lld.h b/os/hal/platforms/STM32/spi_lld.h
index 9e29c5d68..6f1e94096 100644
--- a/os/hal/platforms/STM32/spi_lld.h
+++ b/os/hal/platforms/STM32/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -72,7 +73,7 @@
* over the TX channel.
*/
#if !defined(STM32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI1_DMA_PRIORITY 2
+#define STM32_SPI_SPI1_DMA_PRIORITY 1
#endif
/**
@@ -82,7 +83,7 @@
* over the TX channel.
*/
#if !defined(STM32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI2_DMA_PRIORITY 2
+#define STM32_SPI_SPI2_DMA_PRIORITY 1
#endif
/**
@@ -92,7 +93,7 @@
* over the TX channel.
*/
#if !defined(STM32_SPI_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI3_DMA_PRIORITY 2
+#define STM32_SPI_SPI3_DMA_PRIORITY 1
#endif
/**
@@ -117,30 +118,12 @@
#endif
/**
- * @brief SPI1 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
+ * @brief SPI DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
*/
-#if !defined(STM32_SPI_SPI1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#endif
-
-/**
- * @brief SPI2 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
- */
-#if !defined(STM32_SPI_SPI2_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#endif
-
-/**
- * @brief SPI3 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
- */
-#if !defined(STM32_SPI_SPI3_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
#endif
/*===========================================================================*/
@@ -163,6 +146,10 @@
#error "SPI driver activated but no SPI peripheral assigned"
#endif
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -187,20 +174,20 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
- ioportid_t spc_ssport;
+ ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
- uint16_t spc_sspad;
+ uint16_t sspad;
/**
* @brief SPI initialization data.
*/
- uint16_t spc_cr1;
+ uint16_t cr1;
} SPIConfig;
/**
@@ -210,25 +197,25 @@ struct SPIDriver{
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
@@ -238,19 +225,19 @@ struct SPIDriver{
/**
* @brief Pointer to the SPIx registers block.
*/
- SPI_TypeDef *spd_spi;
+ SPI_TypeDef *spi;
/**
* @brief Pointer to the receive DMA channel registers block.
*/
- stm32_dma_channel_t *spd_dmarx;
+ stm32_dma_channel_t *dmarx;
/**
* @brief Pointer to the transmit DMA channel registers block.
*/
- stm32_dma_channel_t *spd_dmatx;
+ stm32_dma_channel_t *dmatx;
/**
* @brief DMA priority bit mask.
*/
- uint32_t spd_dmaccr;
+ uint32_t dmaccr;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/stm32_dma.c b/os/hal/platforms/STM32/stm32_dma.c
index e25e05ad1..2232df448 100644
--- a/os/hal/platforms/STM32/stm32_dma.c
+++ b/os/hal/platforms/STM32/stm32_dma.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -22,23 +23,43 @@
* @brief STM32 DMA helper driver code.
*
* @addtogroup STM32_DMA
+ * @details DMA sharing helper driver. In the STM32 the DMA channels are a
+ * shared resource, this driver allows to allocate and free DMA
+ * channels at runtime in order to allow all the other device
+ * 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 channels.
* @{
*/
#include "ch.h"
#include "hal.h"
+#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
+
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
-/* Driver local variables. */
+/* Driver local variables and types. */
/*===========================================================================*/
-static cnt_t dmacnt1;
+/**
+ * @brief DMA ISR redirector type.
+ */
+typedef struct {
+ stm32_dmaisr_t dmaisrfunc;
+ void *dmaisrparam;
+} dma_isr_redir_t;
+
+static uint32_t dmamsk1;
+static dma_isr_redir_t dma1[7];
+
#if STM32_HAS_DMA2
-static cnt_t dmacnt2;
+static uint32_t dmamsk2;
+static dma_isr_redir_t dma2[5];
#endif
/*===========================================================================*/
@@ -49,6 +70,258 @@ static cnt_t dmacnt2;
/* Driver interrupt handlers. */
/*===========================================================================*/
+/**
+ * @brief DMA1 channel 1 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_1 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1);
+ if (dma1[0].dmaisrfunc)
+ dma1[0].dmaisrfunc(dma1[0].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 2 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_2 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
+ if (dma1[1].dmaisrfunc)
+ dma1[1].dmaisrfunc(dma1[1].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 3 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_3 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
+ if (dma1[2].dmaisrfunc)
+ dma1[2].dmaisrfunc(dma1[2].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 4 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_4 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
+ if (dma1[3].dmaisrfunc)
+ dma1[3].dmaisrfunc(dma1[3].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 5 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_5 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
+ if (dma1[4].dmaisrfunc)
+ dma1[4].dmaisrfunc(dma1[4].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 6 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_6 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
+ if (dma1[5].dmaisrfunc)
+ dma1[5].dmaisrfunc(dma1[5].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 7 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_7 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
+ if (dma1[6].dmaisrfunc)
+ dma1[6].dmaisrfunc(dma1[6].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
+/**
+ * @brief DMA2 channel 1 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_1 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1);
+ if (dma2[0].dmaisrfunc)
+ dma2[0].dmaisrfunc(dma2[0].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 channel 2 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_2 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_2);
+ if (dma2[1].dmaisrfunc)
+ dma2[1].dmaisrfunc(dma2[1].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 channel 3 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_3 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_3);
+ if (dma2[2].dmaisrfunc)
+ dma2[2].dmaisrfunc(dma2[2].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+#if defined(STM32F10X_CL) || defined(__DOXYGEN__)
+/**
+ * @brief DMA2 channel 4 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ if (dma2[3].dmaisrfunc)
+ dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 channel 5 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
+ if (dma2[4].dmaisrfunc)
+ dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+#else /* !STM32F10X_CL */
+/**
+ * @brief DMA2 channels 4 and 5 shared interrupt handler.
+ * @note This IRQ is shared between DMA2 channels 4 and 5 so it is a
+ * bit less efficient because an extra check.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ /* Check on channel 4.*/
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4);
+ if (isr & DMA_ISR_GIF1) {
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
+ if (dma2[3].dmaisrfunc)
+ dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr);
+ }
+
+ /* Check on channel 5.*/
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4);
+ if (isr & DMA_ISR_GIF1) {
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
+ if (dma2[4].dmaisrfunc)
+ dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr);
+ }
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* !STM32F10X_CL */
+#endif /* STM32_HAS_DMA2 */
+
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
@@ -61,66 +334,135 @@ static cnt_t dmacnt2;
void dmaInit(void) {
int i;
- dmacnt1 = 0;
- for (i = STM32_DMA_CHANNEL_7; i >= STM32_DMA_CHANNEL_1; i--)
+ dmamsk1 = 0;
+ for (i = STM32_DMA_CHANNEL_7; i >= STM32_DMA_CHANNEL_1; i--) {
dmaDisableChannel(STM32_DMA1, i);
+ dma1[i].dmaisrfunc = NULL;
+ }
STM32_DMA1->IFCR = 0xFFFFFFFF;
#if STM32_HAS_DMA2
- dmacnt2 = 0;
- for (i = STM32_DMA_CHANNEL_5; i >= STM32_DMA_CHANNEL_1; i--)
+ dmamsk2 = 0;
+ for (i = STM32_DMA_CHANNEL_5; i >= STM32_DMA_CHANNEL_1; i--) {
dmaDisableChannel(STM32_DMA2, i);
+ dma2[i].dmaisrfunc = NULL;
+ }
STM32_DMA1->IFCR = 0xFFFFFFFF;
#endif
}
/**
- * @brief Enables the specified DMA controller clock.
+ * @brief Allocates a DMA channel.
+ * @details The channel is allocated and, if required, the DMA clock enabled.
+ * Trying to allocate a channel already allocated is an illegal
+ * operation and is trapped if assertions are enabled.
+ * @pre The channel must not be already in use.
+ * @post The channel is allocated and the default ISR handler redirected
+ * to the specified function.
+ * @post The channel must be freed using @p dmaRelease() before it can
+ * be reused with another peripheral.
+ * @note This function can be invoked in both ISR or thread context.
*
- * @param[in] dma the DMA controller id
+ * @param[in] dma DMA controller id
+ * @param[in] channel requested channel id
+ * @param[in] func handling function pointer, can be @p NULL
+ * @param[in] param a parameter to be passed to the handling function
+ * @return The operation status.
+ * @retval FALSE operation successfully allocated.
+ * @retval TRUE the channel was already in use.
*
- * @api
+ * @special
*/
-void dmaEnable(uint32_t dma) {
+void dmaAllocate(uint32_t dma, uint32_t channel,
+ stm32_dmaisr_t func, void *param) {
+ chDbgCheck(func != NULL, "dmaAllocate");
+
+#if STM32_HAS_DMA2
switch (dma) {
- case DMA1_ID:
- if (dmacnt1++ == 0) {
+ case STM32_DMA1_ID:
+#else
+ (void)dma;
+#endif
+ /* Check if the channel is already taken.*/
+ chDbgAssert((dmamsk1 & (1 << channel)) == 0,
+ "dmaAllocate(), #1", "already allocated");
+
+ /* If the DMA unit was idle then the clock is enabled.*/
+ if (dmamsk1 == 0) {
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1->IFCR = 0x0FFFFFFF;
}
- break;
+
+ dmamsk1 |= 1 << channel;
+ dma1[channel].dmaisrfunc = func;
+ dma1[channel].dmaisrparam = param;
#if STM32_HAS_DMA2
- case DMA2_ID:
- if (dmacnt2++ == 0) {
+ break;
+ case STM32_DMA2_ID:
+ /* Check if the channel is already taken.*/
+ chDbgAssert((dmamsk2 & (1 << channel)) == 0,
+ "dmaAllocate(), #2", "already allocated");
+
+ /* If the DMA unit was idle then the clock is enabled.*/
+ if (dmamsk2 == 0) {
RCC->AHBENR |= RCC_AHBENR_DMA2EN;
DMA2->IFCR = 0x0FFFFFFF;
}
+
+ dmamsk2 |= 1 << channel;
+ dma2[channel].dmaisrfunc = func;
+ dma2[channel].dmaisrparam = param;
break;
-#endif
}
+#endif
}
/**
- * @brief Disables the specified DMA controller clock.
+ * @brief Releases a DMA channel.
+ * @details The channel is freed and, if required, the DMA clock disabled.
+ * Trying to release a unallocated channel is an illegal operation
+ * and is trapped if assertions are enabled.
+ * @pre The channel must have been allocated using @p dmaRequest().
+ * @post The channel is again available.
+ * @note This function can be invoked in both ISR or thread context.
*
- * @param[in] dma the DMA controller id
+ * @param[in] dma DMA controller id
+ * @param[in] channel requested channel id
*
- * @api
+ * @special
*/
-void dmaDisable(uint32_t dma) {
+void dmaRelease(uint32_t dma, uint32_t channel) {
+#if STM32_HAS_DMA2
switch (dma) {
- case DMA1_ID:
- if (--dmacnt1 == 0)
+ case STM32_DMA1_ID:
+#else
+ (void)dma;
+#endif
+ /* Check if the channel is not taken.*/
+ chDbgAssert((dmamsk1 & (1 << channel)) != 0,
+ "dmaRelease(), #1", "not allocated");
+
+ dma1[channel].dmaisrfunc = NULL;
+ dmamsk1 &= ~(1 << channel);
+ if (dmamsk1 == 0)
RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
- break;
#if STM32_HAS_DMA2
- case DMA2_ID:
- if (--dmacnt2 == 0)
+ break;
+ case STM32_DMA2_ID:
+ /* Check if the channel is not taken.*/
+ chDbgAssert((dmamsk2 & (1 << channel)) != 0,
+ "dmaRelease(), #2", "not allocated");
+
+ dma2[channel].dmaisrfunc = NULL;
+ dmamsk2 &= ~(1 << channel);
+ if (dmamsk2 == 0)
RCC->AHBENR &= ~RCC_AHBENR_DMA2EN;
break;
-#endif
}
+#endif
}
+#endif /* STM32_DMA_REQUIRED */
+
/** @} */
diff --git a/os/hal/platforms/STM32/stm32_dma.h b/os/hal/platforms/STM32/stm32_dma.h
index 806f79c56..66a2f8c69 100644
--- a/os/hal/platforms/STM32/stm32_dma.h
+++ b/os/hal/platforms/STM32/stm32_dma.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -35,11 +36,11 @@
/*===========================================================================*/
/** @brief DMA1 identifier.*/
-#define DMA1_ID 0
+#define STM32_DMA1_ID 0
/** @brief DMA2 identifier.*/
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
-#define DMA2_ID 1
+#define STM32_DMA2_ID 1
#endif
/*===========================================================================*/
@@ -55,7 +56,7 @@
/*===========================================================================*/
/**
- * @brief STM32 DMA channel memory structure.
+ * @brief STM32 DMA channel memory structure type.
*/
typedef struct {
volatile uint32_t CCR;
@@ -66,7 +67,7 @@ typedef struct {
} stm32_dma_channel_t;
/**
- * @brief STM32 DMA subsystem memory structure.
+ * @brief STM32 DMA subsystem memory structure type.
* @note This structure has been redefined here because it is convenient to
* have the channels organized as an array, the ST header does not
* do that.
@@ -77,6 +78,14 @@ typedef struct {
stm32_dma_channel_t channels[7];
} stm32_dma_t;
+/**
+ * @brief STM32 DMA ISR function type.
+ *
+ * @param[in] p parameter for the registered function
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
+
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
@@ -127,11 +136,12 @@ typedef struct {
/**
* @brief Associates a peripheral data register to a DMA channel.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
* @param[in] cpar value to be written in the CPAR register
*
- * @api
+ * @special
*/
#define dmaChannelSetPeripheral(dmachp, cpar) { \
(dmachp)->CPAR = (uint32_t)(cpar); \
@@ -142,13 +152,14 @@ typedef struct {
* @note This macro does not change the CPAR register because that register
* value does not change frequently, it usually points to a peripheral
* data register.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
* @param[in] cndtr value to be written in the CNDTR register
* @param[in] cmar value to be written in the CMAR register
* @param[in] ccr value to be written in the CCR register
*
- * @api
+ * @special
*/
#define dmaChannelSetup(dmachp, cndtr, cmar, ccr) { \
(dmachp)->CNDTR = (uint32_t)(cndtr); \
@@ -158,10 +169,11 @@ typedef struct {
/**
* @brief DMA channel enable by channel pointer.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
*
- * @api
+ * @special
*/
#define dmaChannelEnable(dmachp) { \
(dmachp)->CCR |= DMA_CCR1_EN; \
@@ -170,10 +182,11 @@ typedef struct {
/**
* @brief DMA channel disable by channel pointer.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
*
- * @api
+ * @special
*/
#define dmaChannelDisable(dmachp) { \
(dmachp)->CCR = 0; \
@@ -186,6 +199,7 @@ typedef struct {
* data register.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
@@ -193,7 +207,7 @@ typedef struct {
* @param[in] cmar value to be written in the CMAR register
* @param[in] ccr value to be written in the CCR register
*
- * @api
+ * @special
*/
#define dmaSetupChannel(dmap, ch, cndtr, cmar, ccr) { \
dmaChannelSetup(&(dmap)->channels[ch], (cndtr), (cmar), (ccr)); \
@@ -203,11 +217,12 @@ typedef struct {
* @brief DMA channel enable by channel ID.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*
- * @api
+ * @special
*/
#define dmaEnableChannel(dmap, ch) { \
dmaChannelEnable(&(dmap)->channels[ch]); \
@@ -217,11 +232,12 @@ typedef struct {
* @brief DMA channel disable by channel ID.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*
- * @api
+ * @special
*/
#define dmaDisableChannel(dmap, ch) { \
dmaChannelDisable(&(dmap)->channels[ch]); \
@@ -233,11 +249,12 @@ typedef struct {
* withdraw all the pending interrupt bits from the ISR register.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*
- * @api
+ * @special
*/
#define dmaClearChannel(dmap, ch){ \
(dmap)->IFCR = 1 << ((ch) * 4); \
@@ -251,8 +268,9 @@ typedef struct {
extern "C" {
#endif
void dmaInit(void);
- void dmaEnable(uint32_t dma);
- void dmaDisable(uint32_t dma);
+ void dmaAllocate(uint32_t dma, uint32_t channel,
+ stm32_dmaisr_t func, void *param);
+ void dmaRelease(uint32_t dma, uint32_t channel);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/platforms/STM32/stm32_usb.h b/os/hal/platforms/STM32/stm32_usb.h
index 8c04ba85f..51e7510c4 100644
--- a/os/hal/platforms/STM32/stm32_usb.h
+++ b/os/hal/platforms/STM32/stm32_usb.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -108,11 +109,16 @@ typedef struct {
#define STM32_USB ((stm32_usb_t *)STM32_USB_BASE)
/**
- * @brief Pointer to the USB RAM.
+ * @brief Pointer to the USB RAM.
*/
#define STM32_USBRAM ((uint32_t *)STM32_USBRAM_BASE)
/**
+ * @brief Size of the dedicated packet memory.
+ */
+#define USB_PMA_SIZE 512
+
+/**
* @brief Mask of all the toggling bits in the EPR register.
*/
#define EPR_TOGGLE_MASK (EPR_STAT_TX_MASK | EPR_DTOG_TX | \
diff --git a/os/hal/platforms/STM32/stm32f10x.h b/os/hal/platforms/STM32/stm32f10x.h
index a6f71cbdb..a187f0a84 100644
--- a/os/hal/platforms/STM32/stm32f10x.h
+++ b/os/hal/platforms/STM32/stm32f10x.h
@@ -2,14 +2,15 @@
******************************************************************************
* @file stm32f10x.h
* @author MCD Application Team
- * @version V3.3.0
- * @date 04/16/2010
- * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File.
- * This file contains all the peripheral register's definitions, bits
- * definitions and memory mapping for STM32F10x Connectivity line, High
- * density, Medium density, Medium density Value line, Low density
- * and Low density Value line and XL-density devices.
- ******************************************************************************
+ * @version V3.4.0
+ * @date 10/15/2010
+ * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File.
+ * This file contains all the peripheral register's definitions, bits
+ * definitions and memory mapping for STM32F10x Connectivity line,
+ * High density, High density value line, Medium density,
+ * Medium density Value line, Low density, Low density Value line
+ * and XL-density devices.
+ ******************************************************************************
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
@@ -29,77 +30,84 @@
/** @addtogroup stm32f10x
* @{
*/
-
+
#ifndef __STM32F10x_H
#define __STM32F10x_H
#ifdef __cplusplus
extern "C" {
-#endif
-
+#endif
+
/** @addtogroup Library_configuration_section
* @{
*/
-
+
/* Uncomment the line below according to the target STM32 device used in your
- application
+ application
*/
-#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
+#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
/* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */
- /* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */
+ /* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */
/* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */
- /* #define STM32F10X_MD_VL */ /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */
+ /* #define STM32F10X_MD_VL */ /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */
/* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */
- #define STM32F10X_XL /*!< STM32F10X_XL: STM32 XL-density devices */
+ /* #define STM32F10X_HD_VL */ /*!< STM32F10X_HD_VL: STM32 High density value line devices */
+ /* #define STM32F10X_XL */ /*!< STM32F10X_XL: STM32 XL-density devices */
/* #define STM32F10X_CL */ /*!< STM32F10X_CL: STM32 Connectivity line devices */
#endif
/* Tip: To avoid modifying this file each time you need to switch between these
devices, you can define the device in your toolchain compiler preprocessor.
- - Low density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
+ - Low-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
where the Flash memory density ranges between 16 and 32 Kbytes.
- Low-density value line devices are STM32F100xx microcontrollers where the Flash
memory density ranges between 16 and 32 Kbytes.
- - Medium density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
+ - Medium-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
where the Flash memory density ranges between 64 and 128 Kbytes.
- - Medium-density value line devices are STM32F100xx microcontrollers where the
- Flash memory density ranges between 64 and 128 Kbytes.
- - High density devices are STM32F101xx and STM32F103xx microcontrollers where
+ - Medium-density value line devices are STM32F100xx microcontrollers where the
+ Flash memory density ranges between 64 and 128 Kbytes.
+ - High-density devices are STM32F101xx and STM32F103xx microcontrollers where
the Flash memory density ranges between 256 and 512 Kbytes.
+ - High-density value line devices are STM32F100xx microcontrollers where the
+ Flash memory density ranges between 256 and 512 Kbytes.
- XL-density devices are STM32F101xx and STM32F103xx microcontrollers where
the Flash memory density ranges between 512 and 1024 Kbytes.
- Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers.
*/
+#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
+ #error "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"
+#endif
+
#if !defined USE_STDPERIPH_DRIVER
/**
* @brief Comment the line below if you will not use the peripherals drivers.
- In this case, these drivers will not be included and the application code will
- be based on direct access to peripherals registers
+ In this case, these drivers will not be included and the application code will
+ be based on direct access to peripherals registers
*/
/*#define USE_STDPERIPH_DRIVER*/
#endif
/**
* @brief In the following line adjust the value of External High Speed oscillator (HSE)
- used in your application
-
+ used in your application
+
Tip: To avoid modifying this file each time you need to use different HSE, you
can define the HSE value in your toolchain compiler preprocessor.
- */
+ */
#if !defined HSE_VALUE
- #ifdef STM32F10X_CL
+ #ifdef STM32F10X_CL
#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
- #else
+ #else
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
#endif /* STM32F10X_CL */
#endif /* HSE_VALUE */
/**
- * @brief In the following line adjust the External High Speed oscillator (HSE) Startup
- Timeout value
+ * @brief In the following line adjust the External High Speed oscillator (HSE) Startup
+ Timeout value
*/
#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */
@@ -109,7 +117,7 @@
* @brief STM32F10x Standard Peripheral Library version number
*/
#define __STM32F10X_STDPERIPH_VERSION_MAIN (0x03) /*!< [31:16] STM32F10x Standard Peripheral Library main version */
-#define __STM32F10X_STDPERIPH_VERSION_SUB1 (0x03) /*!< [15:8] STM32F10x Standard Peripheral Library sub1 version */
+#define __STM32F10X_STDPERIPH_VERSION_SUB1 (0x04) /*!< [15:8] STM32F10x Standard Peripheral Library sub1 version */
#define __STM32F10X_STDPERIPH_VERSION_SUB2 (0x00) /*!< [7:0] STM32F10x Standard Peripheral Library sub2 version */
#define __STM32F10X_STDPERIPH_VERSION ((__STM32F10X_STDPERIPH_VERSION_MAIN << 16)\
| (__STM32F10X_STDPERIPH_VERSION_SUB1 << 8)\
@@ -124,7 +132,7 @@
*/
/**
- * @brief Configuration of the Cortex-M3 Processor and Core Peripherals
+ * @brief Configuration of the Cortex-M3 Processor and Core Peripherals
*/
#ifdef STM32F10X_XL
#define __MPU_PRESENT 1 /*!< STM32 XL-density devices provide an MPU */
@@ -135,8 +143,8 @@
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
/**
- * @brief STM32F10x Interrupt Number Definition, according to the selected device
- * in @ref Library_configuration_section
+ * @brief STM32F10x Interrupt Number Definition, according to the selected device
+ * in @ref Library_configuration_section
*/
typedef enum IRQn
{
@@ -190,8 +198,8 @@ typedef enum IRQn
USART2_IRQn = 38, /*!< USART2 global Interrupt */
EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
- USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
-#endif /* STM32F10X_LD */
+ USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
+#endif /* STM32F10X_LD */
#ifdef STM32F10X_LD_VL
ADC1_IRQn = 18, /*!< ADC1 global Interrupt */
@@ -209,9 +217,9 @@ typedef enum IRQn
USART2_IRQn = 38, /*!< USART2 global Interrupt */
EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
- CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */
- TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */
- TIM7_IRQn = 55 /*!< TIM7 Interrupt */
+ CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */
+ TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */
+ TIM7_IRQn = 55 /*!< TIM7 Interrupt */
#endif /* STM32F10X_LD_VL */
#ifdef STM32F10X_MD
@@ -239,8 +247,8 @@ typedef enum IRQn
USART3_IRQn = 39, /*!< USART3 global Interrupt */
EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
- USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
-#endif /* STM32F10X_MD */
+ USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
+#endif /* STM32F10X_MD */
#ifdef STM32F10X_MD_VL
ADC1_IRQn = 18, /*!< ADC1 global Interrupt */
@@ -263,9 +271,9 @@ typedef enum IRQn
USART3_IRQn = 39, /*!< USART3 global Interrupt */
EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
- CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */
- TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */
- TIM7_IRQn = 55 /*!< TIM7 Interrupt */
+ CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */
+ TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */
+ TIM7_IRQn = 55 /*!< TIM7 Interrupt */
#endif /* STM32F10X_MD_VL */
#ifdef STM32F10X_HD
@@ -311,7 +319,48 @@ typedef enum IRQn
DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
-#endif /* STM32F10X_HD */
+#endif /* STM32F10X_HD */
+
+#ifdef STM32F10X_HD_VL
+ ADC1_IRQn = 18, /*!< ADC1 global Interrupt */
+ EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
+ TIM1_BRK_TIM15_IRQn = 24, /*!< TIM1 Break and TIM15 Interrupts */
+ TIM1_UP_TIM16_IRQn = 25, /*!< TIM1 Update and TIM16 Interrupts */
+ TIM1_TRG_COM_TIM17_IRQn = 26, /*!< TIM1 Trigger and Commutation and TIM17 Interrupt */
+ TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
+ TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
+ TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
+ TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
+ I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
+ I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
+ I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
+ I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
+ SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
+ SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
+ USART1_IRQn = 37, /*!< USART1 global Interrupt */
+ USART2_IRQn = 38, /*!< USART2 global Interrupt */
+ USART3_IRQn = 39, /*!< USART3 global Interrupt */
+ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
+ RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
+ CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */
+ TIM12_IRQn = 43, /*!< TIM12 global Interrupt */
+ TIM13_IRQn = 44, /*!< TIM13 global Interrupt */
+ TIM14_IRQn = 45, /*!< TIM14 global Interrupt */
+ FSMC_IRQn = 48, /*!< FSMC global Interrupt */
+ TIM5_IRQn = 50, /*!< TIM5 global Interrupt */
+ SPI3_IRQn = 51, /*!< SPI3 global Interrupt */
+ UART4_IRQn = 52, /*!< UART4 global Interrupt */
+ UART5_IRQn = 53, /*!< UART5 global Interrupt */
+ TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */
+ TIM7_IRQn = 55, /*!< TIM7 Interrupt */
+ DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */
+ DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
+ DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
+ DMA2_Channel4_5_IRQn = 59, /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
+ DMA2_Channel5_IRQn = 60 /*!< DMA2 Channel 5 global Interrupt (DMA2 Channel 5 is
+ mapped at postion 60 only if the MISC_REMAP bit in
+ the AFIO_MAPR2 register is set) */
+#endif /* STM32F10X_HD_VL */
#ifdef STM32F10X_XL
ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
@@ -356,7 +405,7 @@ typedef enum IRQn
DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
-#endif /* STM32F10X_XL */
+#endif /* STM32F10X_XL */
#ifdef STM32F10X_CL
ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
@@ -402,7 +451,7 @@ typedef enum IRQn
CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */
CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */
OTG_FS_IRQn = 67 /*!< USB OTG FS global Interrupt */
-#endif /* STM32F10X_CL */
+#endif /* STM32F10X_CL */
} IRQn_Type;
/**
@@ -415,7 +464,7 @@ typedef enum IRQn
/** @addtogroup Exported_types
* @{
- */
+ */
/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */
typedef int32_t s32;
@@ -450,10 +499,6 @@ typedef __I uint32_t vuc32; /*!< Read Only */
typedef __I uint16_t vuc16; /*!< Read Only */
typedef __I uint8_t vuc8; /*!< Read Only */
-#ifndef __cplusplus
-typedef enum {FALSE = 0, TRUE = !FALSE} bool;
-#endif
-
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
@@ -471,10 +516,10 @@ typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
/** @addtogroup Peripheral_registers_structures
* @{
- */
+ */
-/**
- * @brief Analog to Digital Converter
+/**
+ * @brief Analog to Digital Converter
*/
typedef struct
@@ -501,8 +546,8 @@ typedef struct
__IO uint32_t DR;
} ADC_TypeDef;
-/**
- * @brief Backup Registers
+/**
+ * @brief Backup Registers
*/
typedef struct
@@ -527,7 +572,7 @@ typedef struct
__IO uint16_t DR9;
uint16_t RESERVED9;
__IO uint16_t DR10;
- uint16_t RESERVED10;
+ uint16_t RESERVED10;
__IO uint16_t RTCCR;
uint16_t RESERVED11;
__IO uint16_t CR;
@@ -573,7 +618,7 @@ typedef struct
__IO uint16_t DR29;
uint16_t RESERVED32;
__IO uint16_t DR30;
- uint16_t RESERVED33;
+ uint16_t RESERVED33;
__IO uint16_t DR31;
uint16_t RESERVED34;
__IO uint16_t DR32;
@@ -597,11 +642,11 @@ typedef struct
__IO uint16_t DR41;
uint16_t RESERVED44;
__IO uint16_t DR42;
- uint16_t RESERVED45;
+ uint16_t RESERVED45;
} BKP_TypeDef;
-
-/**
- * @brief Controller Area Network TxMailBox
+
+/**
+ * @brief Controller Area Network TxMailBox
*/
typedef struct
@@ -612,10 +657,10 @@ typedef struct
__IO uint32_t TDHR;
} CAN_TxMailBox_TypeDef;
-/**
- * @brief Controller Area Network FIFOMailBox
+/**
+ * @brief Controller Area Network FIFOMailBox
*/
-
+
typedef struct
{
__IO uint32_t RIR;
@@ -624,20 +669,20 @@ typedef struct
__IO uint32_t RDHR;
} CAN_FIFOMailBox_TypeDef;
-/**
- * @brief Controller Area Network FilterRegister
+/**
+ * @brief Controller Area Network FilterRegister
*/
-
+
typedef struct
{
__IO uint32_t FR1;
__IO uint32_t FR2;
} CAN_FilterRegister_TypeDef;
-/**
- * @brief Controller Area Network
+/**
+ * @brief Controller Area Network
*/
-
+
typedef struct
{
__IO uint32_t MCR;
@@ -665,10 +710,10 @@ typedef struct
CAN_FilterRegister_TypeDef sFilterRegister[14];
#else
CAN_FilterRegister_TypeDef sFilterRegister[28];
-#endif /* STM32F10X_CL */
+#endif /* STM32F10X_CL */
} CAN_TypeDef;
-/**
+/**
* @brief Consumer Electronics Control (CEC)
*/
typedef struct
@@ -679,11 +724,11 @@ typedef struct
__IO uint32_t ESR;
__IO uint32_t CSR;
__IO uint32_t TXD;
- __IO uint32_t RXD;
+ __IO uint32_t RXD;
} CEC_TypeDef;
-/**
- * @brief CRC calculation unit
+/**
+ * @brief CRC calculation unit
*/
typedef struct
@@ -695,7 +740,7 @@ typedef struct
__IO uint32_t CR;
} CRC_TypeDef;
-/**
+/**
* @brief Digital to Analog Converter
*/
@@ -714,22 +759,22 @@ typedef struct
__IO uint32_t DHR8RD;
__IO uint32_t DOR1;
__IO uint32_t DOR2;
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
__IO uint32_t SR;
#endif
} DAC_TypeDef;
-/**
+/**
* @brief Debug MCU
*/
typedef struct
{
__IO uint32_t IDCODE;
- __IO uint32_t CR;
+ __IO uint32_t CR;
}DBGMCU_TypeDef;
-/**
+/**
* @brief DMA Controller
*/
@@ -747,7 +792,7 @@ typedef struct
__IO uint32_t IFCR;
} DMA_TypeDef;
-/**
+/**
* @brief Ethernet MAC
*/
@@ -818,7 +863,7 @@ typedef struct
__IO uint32_t DMACHRBAR;
} ETH_TypeDef;
-/**
+/**
* @brief External Interrupt/Event Controller
*/
@@ -832,7 +877,7 @@ typedef struct
__IO uint32_t PR;
} EXTI_TypeDef;
-/**
+/**
* @brief FLASH Registers
*/
@@ -848,19 +893,19 @@ typedef struct
__IO uint32_t OBR;
__IO uint32_t WRPR;
#ifdef STM32F10X_XL
- uint32_t RESERVED1[8];
+ uint32_t RESERVED1[8];
__IO uint32_t KEYR2;
- uint32_t RESERVED2;
+ uint32_t RESERVED2;
__IO uint32_t SR2;
__IO uint32_t CR2;
- __IO uint32_t AR2;
-#endif /* STM32F10X_XL */
+ __IO uint32_t AR2;
+#endif /* STM32F10X_XL */
} FLASH_TypeDef;
-/**
+/**
* @brief Option Bytes Registers
*/
-
+
typedef struct
{
__IO uint16_t RDP;
@@ -873,66 +918,66 @@ typedef struct
__IO uint16_t WRP3;
} OB_TypeDef;
-/**
+/**
* @brief Flexible Static Memory Controller
*/
typedef struct
{
- __IO uint32_t BTCR[8];
-} FSMC_Bank1_TypeDef;
+ __IO uint32_t BTCR[8];
+} FSMC_Bank1_TypeDef;
-/**
+/**
* @brief Flexible Static Memory Controller Bank1E
*/
-
+
typedef struct
{
__IO uint32_t BWTR[7];
} FSMC_Bank1E_TypeDef;
-/**
+/**
* @brief Flexible Static Memory Controller Bank2
*/
-
+
typedef struct
{
__IO uint32_t PCR2;
__IO uint32_t SR2;
__IO uint32_t PMEM2;
__IO uint32_t PATT2;
- uint32_t RESERVED0;
- __IO uint32_t ECCR2;
-} FSMC_Bank2_TypeDef;
+ uint32_t RESERVED0;
+ __IO uint32_t ECCR2;
+} FSMC_Bank2_TypeDef;
-/**
+/**
* @brief Flexible Static Memory Controller Bank3
*/
-
+
typedef struct
{
__IO uint32_t PCR3;
__IO uint32_t SR3;
__IO uint32_t PMEM3;
__IO uint32_t PATT3;
- uint32_t RESERVED0;
- __IO uint32_t ECCR3;
-} FSMC_Bank3_TypeDef;
+ uint32_t RESERVED0;
+ __IO uint32_t ECCR3;
+} FSMC_Bank3_TypeDef;
-/**
+/**
* @brief Flexible Static Memory Controller Bank4
*/
-
+
typedef struct
{
__IO uint32_t PCR4;
__IO uint32_t SR4;
__IO uint32_t PMEM4;
__IO uint32_t PATT4;
- __IO uint32_t PIO4;
-} FSMC_Bank4_TypeDef;
+ __IO uint32_t PIO4;
+} FSMC_Bank4_TypeDef;
-/**
+/**
* @brief General Purpose I/O
*/
@@ -947,7 +992,7 @@ typedef struct
__IO uint32_t LCKR;
} GPIO_TypeDef;
-/**
+/**
* @brief Alternate Function I/O
*/
@@ -957,9 +1002,9 @@ typedef struct
__IO uint32_t MAPR;
__IO uint32_t EXTICR[4];
uint32_t RESERVED0;
- __IO uint32_t MAPR2;
+ __IO uint32_t MAPR2;
} AFIO_TypeDef;
-/**
+/**
* @brief Inter-integrated Circuit Interface
*/
@@ -985,7 +1030,7 @@ typedef struct
uint16_t RESERVED8;
} I2C_TypeDef;
-/**
+/**
* @brief Independent WATCHDOG
*/
@@ -997,7 +1042,7 @@ typedef struct
__IO uint32_t SR;
} IWDG_TypeDef;
-/**
+/**
* @brief Power Control
*/
@@ -1007,7 +1052,7 @@ typedef struct
__IO uint32_t CSR;
} PWR_TypeDef;
-/**
+/**
* @brief Reset and Clock Control
*/
@@ -1024,18 +1069,18 @@ typedef struct
__IO uint32_t BDCR;
__IO uint32_t CSR;
-#ifdef STM32F10X_CL
+#ifdef STM32F10X_CL
__IO uint32_t AHBRSTR;
__IO uint32_t CFGR2;
-#endif /* STM32F10X_CL */
+#endif /* STM32F10X_CL */
-#if defined STM32F10X_LD_VL || defined STM32F10X_MD_VL
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
uint32_t RESERVED0;
__IO uint32_t CFGR2;
-#endif /* STM32F10X_LD_VL || STM32F10X_MD_VL */
+#endif /* STM32F10X_LD_VL || STM32F10X_MD_VL || STM32F10X_HD_VL */
} RCC_TypeDef;
-/**
+/**
* @brief Real-Time Clock
*/
@@ -1063,7 +1108,7 @@ typedef struct
uint16_t RESERVED9;
} RTC_TypeDef;
-/**
+/**
* @brief SD host Interface
*/
@@ -1091,7 +1136,7 @@ typedef struct
__IO uint32_t FIFO;
} SDIO_TypeDef;
-/**
+/**
* @brief Serial Peripheral Interface
*/
@@ -1114,10 +1159,10 @@ typedef struct
__IO uint16_t I2SCFGR;
uint16_t RESERVED7;
__IO uint16_t I2SPR;
- uint16_t RESERVED8;
+ uint16_t RESERVED8;
} SPI_TypeDef;
-/**
+/**
* @brief TIM
*/
@@ -1165,10 +1210,10 @@ typedef struct
uint16_t RESERVED19;
} TIM_TypeDef;
-/**
+/**
* @brief Universal Synchronous Asynchronous Receiver Transmitter
*/
-
+
typedef struct
{
__IO uint16_t SR;
@@ -1187,7 +1232,7 @@ typedef struct
uint16_t RESERVED6;
} USART_TypeDef;
-/**
+/**
* @brief Window WATCHDOG
*/
@@ -1201,16 +1246,18 @@ typedef struct
/**
* @}
*/
-
+
/** @addtogroup Peripheral_memory_map
* @{
*/
-#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the alias region */
-#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the alias region */
-#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM base address in the bit-band region */
-#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the bit-band region */
+#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH base address in the alias region */
+#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM base address in the alias region */
+#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
+
+#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the bit-band region */
+#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */
#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */
@@ -1308,10 +1355,10 @@ typedef struct
/**
* @}
*/
-
+
/** @addtogroup Peripheral_declaration
* @{
- */
+ */
#define TIM2 ((TIM_TypeDef *) TIM2_BASE)
#define TIM3 ((TIM_TypeDef *) TIM3_BASE)
@@ -1379,7 +1426,7 @@ typedef struct
#define RCC ((RCC_TypeDef *) RCC_BASE)
#define CRC ((CRC_TypeDef *) CRC_BASE)
#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE)
-#define OB ((OB_TypeDef *) OB_BASE)
+#define OB ((OB_TypeDef *) OB_BASE)
#define ETH ((ETH_TypeDef *) ETH_BASE)
#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE)
#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE)
@@ -1395,11 +1442,11 @@ typedef struct
/** @addtogroup Exported_constants
* @{
*/
-
+
/** @addtogroup Peripheral_Registers_Bits_Definition
* @{
*/
-
+
/******************************************************************************/
/* Peripheral Registers_Bits_Definition */
/******************************************************************************/
@@ -1727,9 +1774,9 @@ typedef struct
#define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock * 8 */
#define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock * 9 */
#define RCC_CFGR_PLLMULL6_5 ((uint32_t)0x00340000) /*!< PLL input clock * 6.5 */
-
+
#define RCC_CFGR_OTGFSPRE ((uint32_t)0x00400000) /*!< USB OTG FS prescaler */
-
+
/*!< MCO configuration */
#define RCC_CFGR_MCO ((uint32_t)0x0F000000) /*!< MCO[3:0] bits (Microcontroller Clock Output) */
#define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */
@@ -1746,7 +1793,7 @@ typedef struct
#define RCC_CFGR_MCO_PLL3CLK_Div2 ((uint32_t)0x09000000) /*!< PLL3 clock divided by 2 selected as MCO source*/
#define RCC_CFGR_MCO_Ext_HSE ((uint32_t)0x0A000000) /*!< XT1 external 3-25 MHz oscillator clock selected as MCO source */
#define RCC_CFGR_MCO_PLL3CLK ((uint32_t)0x0B000000) /*!< PLL3 clock selected as MCO source */
-#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
#define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */
#define RCC_CFGR_PLLSRC_PREDIV1 ((uint32_t)0x00010000) /*!< PREDIV1 clock selected as PLL entry clock source */
@@ -1853,7 +1900,7 @@ typedef struct
#define RCC_APB2RSTR_IOPDRST ((uint32_t)0x00000020) /*!< I/O port D reset */
#define RCC_APB2RSTR_ADC1RST ((uint32_t)0x00000200) /*!< ADC 1 interface reset */
-#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL)
+#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL)
#define RCC_APB2RSTR_ADC2RST ((uint32_t)0x00000400) /*!< ADC 2 interface reset */
#endif
@@ -1861,7 +1908,7 @@ typedef struct
#define RCC_APB2RSTR_SPI1RST ((uint32_t)0x00001000) /*!< SPI 1 reset */
#define RCC_APB2RSTR_USART1RST ((uint32_t)0x00004000) /*!< USART1 reset */
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
#define RCC_APB2RSTR_TIM15RST ((uint32_t)0x00010000) /*!< TIM15 Timer reset */
#define RCC_APB2RSTR_TIM16RST ((uint32_t)0x00020000) /*!< TIM16 Timer reset */
#define RCC_APB2RSTR_TIM17RST ((uint32_t)0x00040000) /*!< TIM17 Timer reset */
@@ -1878,6 +1925,11 @@ typedef struct
#define RCC_APB2RSTR_ADC3RST ((uint32_t)0x00008000) /*!< ADC3 interface reset */
#endif
+#if defined (STM32F10X_HD_VL)
+ #define RCC_APB2RSTR_IOPFRST ((uint32_t)0x00000080) /*!< I/O port F reset */
+ #define RCC_APB2RSTR_IOPGRST ((uint32_t)0x00000100) /*!< I/O port G reset */
+#endif
+
#ifdef STM32F10X_XL
#define RCC_APB2RSTR_TIM9RST ((uint32_t)0x00080000) /*!< TIM9 Timer reset */
#define RCC_APB2RSTR_TIM10RST ((uint32_t)0x00100000) /*!< TIM10 Timer reset */
@@ -1891,7 +1943,7 @@ typedef struct
#define RCC_APB1RSTR_USART2RST ((uint32_t)0x00020000) /*!< USART 2 reset */
#define RCC_APB1RSTR_I2C1RST ((uint32_t)0x00200000) /*!< I2C 1 reset */
-#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL)
+#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL)
#define RCC_APB1RSTR_CAN1RST ((uint32_t)0x02000000) /*!< CAN1 reset */
#endif
@@ -1919,11 +1971,21 @@ typedef struct
#define RCC_APB1RSTR_DACRST ((uint32_t)0x20000000) /*!< DAC interface reset */
#endif
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
#define RCC_APB1RSTR_TIM6RST ((uint32_t)0x00000010) /*!< Timer 6 reset */
#define RCC_APB1RSTR_TIM7RST ((uint32_t)0x00000020) /*!< Timer 7 reset */
#define RCC_APB1RSTR_DACRST ((uint32_t)0x20000000) /*!< DAC interface reset */
- #define RCC_APB1RSTR_CECRST ((uint32_t)0x40000000) /*!< CEC interface reset */
+ #define RCC_APB1RSTR_CECRST ((uint32_t)0x40000000) /*!< CEC interface reset */
+#endif
+
+#if defined (STM32F10X_HD_VL)
+ #define RCC_APB1RSTR_TIM5RST ((uint32_t)0x00000008) /*!< Timer 5 reset */
+ #define RCC_APB1RSTR_TIM12RST ((uint32_t)0x00000040) /*!< TIM12 Timer reset */
+ #define RCC_APB1RSTR_TIM13RST ((uint32_t)0x00000080) /*!< TIM13 Timer reset */
+ #define RCC_APB1RSTR_TIM14RST ((uint32_t)0x00000100) /*!< TIM14 Timer reset */
+ #define RCC_APB1RSTR_SPI3RST ((uint32_t)0x00008000) /*!< SPI 3 reset */
+ #define RCC_APB1RSTR_UART4RST ((uint32_t)0x00080000) /*!< UART 4 reset */
+ #define RCC_APB1RSTR_UART5RST ((uint32_t)0x00100000) /*!< UART 5 reset */
#endif
#ifdef STM32F10X_CL
@@ -1942,7 +2004,7 @@ typedef struct
#define RCC_AHBENR_FLITFEN ((uint16_t)0x0010) /*!< FLITF clock enable */
#define RCC_AHBENR_CRCEN ((uint16_t)0x0040) /*!< CRC clock enable */
-#if defined (STM32F10X_HD) || defined (STM32F10X_CL)
+#if defined (STM32F10X_HD) || defined (STM32F10X_CL) || defined (STM32F10X_HD_VL) || defined (STM32F10X_XL)
#define RCC_AHBENR_DMA2EN ((uint16_t)0x0002) /*!< DMA2 clock enable */
#endif
@@ -1951,6 +2013,10 @@ typedef struct
#define RCC_AHBENR_SDIOEN ((uint16_t)0x0400) /*!< SDIO clock enable */
#endif
+#if defined (STM32F10X_HD_VL)
+ #define RCC_AHBENR_FSMCEN ((uint16_t)0x0100) /*!< FSMC clock enable */
+#endif
+
#ifdef STM32F10X_CL
#define RCC_AHBENR_OTGFSEN ((uint32_t)0x00001000) /*!< USB OTG FS clock enable */
#define RCC_AHBENR_ETHMACEN ((uint32_t)0x00004000) /*!< ETHERNET MAC clock enable */
@@ -1966,7 +2032,7 @@ typedef struct
#define RCC_APB2ENR_IOPDEN ((uint32_t)0x00000020) /*!< I/O port D clock enable */
#define RCC_APB2ENR_ADC1EN ((uint32_t)0x00000200) /*!< ADC 1 interface clock enable */
-#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL)
+#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL)
#define RCC_APB2ENR_ADC2EN ((uint32_t)0x00000400) /*!< ADC 2 interface clock enable */
#endif
@@ -1974,7 +2040,7 @@ typedef struct
#define RCC_APB2ENR_SPI1EN ((uint32_t)0x00001000) /*!< SPI 1 clock enable */
#define RCC_APB2ENR_USART1EN ((uint32_t)0x00004000) /*!< USART1 clock enable */
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
#define RCC_APB2ENR_TIM15EN ((uint32_t)0x00010000) /*!< TIM15 Timer clock enable */
#define RCC_APB2ENR_TIM16EN ((uint32_t)0x00020000) /*!< TIM16 Timer clock enable */
#define RCC_APB2ENR_TIM17EN ((uint32_t)0x00040000) /*!< TIM17 Timer clock enable */
@@ -1991,6 +2057,11 @@ typedef struct
#define RCC_APB2ENR_ADC3EN ((uint32_t)0x00008000) /*!< DMA1 clock enable */
#endif
+#if defined (STM32F10X_HD_VL)
+ #define RCC_APB2ENR_IOPFEN ((uint32_t)0x00000080) /*!< I/O port F clock enable */
+ #define RCC_APB2ENR_IOPGEN ((uint32_t)0x00000100) /*!< I/O port G clock enable */
+#endif
+
#ifdef STM32F10X_XL
#define RCC_APB2ENR_TIM9EN ((uint32_t)0x00080000) /*!< TIM9 Timer clock enable */
#define RCC_APB2ENR_TIM10EN ((uint32_t)0x00100000) /*!< TIM10 Timer clock enable */
@@ -2004,7 +2075,7 @@ typedef struct
#define RCC_APB1ENR_USART2EN ((uint32_t)0x00020000) /*!< USART 2 clock enable */
#define RCC_APB1ENR_I2C1EN ((uint32_t)0x00200000) /*!< I2C 1 clock enable */
-#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL)
+#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL)
#define RCC_APB1ENR_CAN1EN ((uint32_t)0x02000000) /*!< CAN1 clock enable */
#endif
@@ -2032,13 +2103,23 @@ typedef struct
#define RCC_APB1ENR_DACEN ((uint32_t)0x20000000) /*!< DAC interface clock enable */
#endif
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
#define RCC_APB1ENR_TIM6EN ((uint32_t)0x00000010) /*!< Timer 6 clock enable */
#define RCC_APB1ENR_TIM7EN ((uint32_t)0x00000020) /*!< Timer 7 clock enable */
#define RCC_APB1ENR_DACEN ((uint32_t)0x20000000) /*!< DAC interface clock enable */
- #define RCC_APB1ENR_CECEN ((uint32_t)0x40000000) /*!< CEC interface clock enable */
+ #define RCC_APB1ENR_CECEN ((uint32_t)0x40000000) /*!< CEC interface clock enable */
#endif
+#ifdef STM32F10X_HD_VL
+ #define RCC_APB1ENR_TIM5EN ((uint32_t)0x00000008) /*!< Timer 5 clock enable */
+ #define RCC_APB1ENR_TIM12EN ((uint32_t)0x00000040) /*!< TIM12 Timer clock enable */
+ #define RCC_APB1ENR_TIM13EN ((uint32_t)0x00000080) /*!< TIM13 Timer clock enable */
+ #define RCC_APB1ENR_TIM14EN ((uint32_t)0x00000100) /*!< TIM14 Timer clock enable */
+ #define RCC_APB1ENR_SPI3EN ((uint32_t)0x00008000) /*!< SPI 3 clock enable */
+ #define RCC_APB1ENR_UART4EN ((uint32_t)0x00080000) /*!< UART 4 clock enable */
+ #define RCC_APB1ENR_UART5EN ((uint32_t)0x00100000) /*!< UART 5 clock enable */
+#endif /* STM32F10X_HD_VL */
+
#ifdef STM32F10X_CL
#define RCC_APB1ENR_CAN2EN ((uint32_t)0x04000000) /*!< CAN2 clock enable */
#endif /* STM32F10X_CL */
@@ -2067,7 +2148,7 @@ typedef struct
#define RCC_BDCR_RTCEN ((uint32_t)0x00008000) /*!< RTC clock enable */
#define RCC_BDCR_BDRST ((uint32_t)0x00010000) /*!< Backup domain software reset */
-/******************* Bit definition for RCC_CSR register ********************/
+/******************* Bit definition for RCC_CSR register ********************/
#define RCC_CSR_LSION ((uint32_t)0x00000001) /*!< Internal Low Speed oscillator enable */
#define RCC_CSR_LSIRDY ((uint32_t)0x00000002) /*!< Internal Low Speed oscillator Ready */
#define RCC_CSR_RMVF ((uint32_t)0x01000000) /*!< Remove reset flag */
@@ -2173,7 +2254,7 @@ typedef struct
#define RCC_CFGR2_I2S3SRC ((uint32_t)0x00040000) /*!< I2S3 clock source */
#endif /* STM32F10X_CL */
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
/******************* Bit definition for RCC_CFGR2 register ******************/
/*!< PREDIV1 configuration */
#define RCC_CFGR2_PREDIV1 ((uint32_t)0x0000000F) /*!< PREDIV1[3:0] bits */
@@ -2199,7 +2280,7 @@ typedef struct
#define RCC_CFGR2_PREDIV1_DIV15 ((uint32_t)0x0000000E) /*!< PREDIV1 input clock divided by 15 */
#define RCC_CFGR2_PREDIV1_DIV16 ((uint32_t)0x0000000F) /*!< PREDIV1 input clock divided by 16 */
#endif
-
+
/******************************************************************************/
/* */
/* General Purpose and Alternate Function I/O */
@@ -2609,7 +2690,7 @@ typedef struct
#define AFIO_EXTICR1_EXTI1_PF ((uint16_t)0x0050) /*!< PF[1] pin */
#define AFIO_EXTICR1_EXTI1_PG ((uint16_t)0x0060) /*!< PG[1] pin */
-/*!< EXTI2 configuration */
+/*!< EXTI2 configuration */
#define AFIO_EXTICR1_EXTI2_PA ((uint16_t)0x0000) /*!< PA[2] pin */
#define AFIO_EXTICR1_EXTI2_PB ((uint16_t)0x0100) /*!< PB[2] pin */
#define AFIO_EXTICR1_EXTI2_PC ((uint16_t)0x0200) /*!< PC[2] pin */
@@ -2651,7 +2732,7 @@ typedef struct
#define AFIO_EXTICR2_EXTI5_PF ((uint16_t)0x0050) /*!< PF[5] pin */
#define AFIO_EXTICR2_EXTI5_PG ((uint16_t)0x0060) /*!< PG[5] pin */
-/*!< EXTI6 configuration */
+/*!< EXTI6 configuration */
#define AFIO_EXTICR2_EXTI6_PA ((uint16_t)0x0000) /*!< PA[6] pin */
#define AFIO_EXTICR2_EXTI6_PB ((uint16_t)0x0100) /*!< PB[6] pin */
#define AFIO_EXTICR2_EXTI6_PC ((uint16_t)0x0200) /*!< PC[6] pin */
@@ -2693,7 +2774,7 @@ typedef struct
#define AFIO_EXTICR3_EXTI9_PF ((uint16_t)0x0050) /*!< PF[9] pin */
#define AFIO_EXTICR3_EXTI9_PG ((uint16_t)0x0060) /*!< PG[9] pin */
-/*!< EXTI10 configuration */
+/*!< EXTI10 configuration */
#define AFIO_EXTICR3_EXTI10_PA ((uint16_t)0x0000) /*!< PA[10] pin */
#define AFIO_EXTICR3_EXTI10_PB ((uint16_t)0x0100) /*!< PB[10] pin */
#define AFIO_EXTICR3_EXTI10_PC ((uint16_t)0x0200) /*!< PC[10] pin */
@@ -2735,7 +2816,7 @@ typedef struct
#define AFIO_EXTICR4_EXTI13_PF ((uint16_t)0x0050) /*!< PF[13] pin */
#define AFIO_EXTICR4_EXTI13_PG ((uint16_t)0x0060) /*!< PG[13] pin */
-/*!< EXTI14 configuration */
+/*!< EXTI14 configuration */
#define AFIO_EXTICR4_EXTI14_PA ((uint16_t)0x0000) /*!< PA[14] pin */
#define AFIO_EXTICR4_EXTI14_PB ((uint16_t)0x0100) /*!< PB[14] pin */
#define AFIO_EXTICR4_EXTI14_PC ((uint16_t)0x0200) /*!< PC[14] pin */
@@ -2753,7 +2834,7 @@ typedef struct
#define AFIO_EXTICR4_EXTI15_PF ((uint16_t)0x5000) /*!< PF[15] pin */
#define AFIO_EXTICR4_EXTI15_PG ((uint16_t)0x6000) /*!< PG[15] pin */
-#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL)
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
/****************** Bit definition for AFIO_MAPR2 register ******************/
#define AFIO_MAPR2_TIM15_REMAP ((uint32_t)0x00000001) /*!< TIM15 remapping */
#define AFIO_MAPR2_TIM16_REMAP ((uint32_t)0x00000002) /*!< TIM16 remapping */
@@ -2762,7 +2843,16 @@ typedef struct
#define AFIO_MAPR2_TIM1_DMA_REMAP ((uint32_t)0x00000010) /*!< TIM1_DMA remapping */
#endif
-#ifdef STM32F10X_XL
+#ifdef STM32F10X_HD_VL
+#define AFIO_MAPR2_TIM13_REMAP ((uint32_t)0x00000100) /*!< TIM13 remapping */
+#define AFIO_MAPR2_TIM14_REMAP ((uint32_t)0x00000200) /*!< TIM14 remapping */
+#define AFIO_MAPR2_FSMC_NADV_REMAP ((uint32_t)0x00000400) /*!< FSMC NADV remapping */
+#define AFIO_MAPR2_TIM67_DAC_DMA_REMAP ((uint32_t)0x00000800) /*!< TIM6/TIM7 and DAC DMA remapping */
+#define AFIO_MAPR2_TIM12_REMAP ((uint32_t)0x00001000) /*!< TIM12 remapping */
+#define AFIO_MAPR2_MISC_REMAP ((uint32_t)0x00002000) /*!< Miscellaneous remapping */
+#endif
+
+#ifdef STM32F10X_XL
/****************** Bit definition for AFIO_MAPR2 register ******************/
#define AFIO_MAPR2_TIM9_REMAP ((uint32_t)0x00000020) /*!< TIM9 remapping */
#define AFIO_MAPR2_TIM10_REMAP ((uint32_t)0x00000040) /*!< TIM10 remapping */
@@ -3630,7 +3720,7 @@ typedef struct
#define ADC_CR1_JAWDEN ((uint32_t)0x00400000) /*!<Analog watchdog enable on injected channels */
#define ADC_CR1_AWDEN ((uint32_t)0x00800000) /*!<Analog watchdog enable on regular channels */
-
+
/******************* Bit definition for ADC_CR2 register ********************/
#define ADC_CR2_ADON ((uint32_t)0x00000001) /*!<A/D Converter ON / OFF */
#define ADC_CR2_CONT ((uint32_t)0x00000002) /*!<Continuous Conversion */
@@ -3888,7 +3978,7 @@ typedef struct
#define ADC_SQR3_SQ6_4 ((uint32_t)0x20000000) /*!<Bit 4 */
/******************* Bit definition for ADC_JSQR register *******************/
-#define ADC_JSQR_JSQ1 ((uint32_t)0x0000001F) /*!<JSQ1[4:0] bits (1st conversion in injected sequence) */
+#define ADC_JSQR_JSQ1 ((uint32_t)0x0000001F) /*!<JSQ1[4:0] bits (1st conversion in injected sequence) */
#define ADC_JSQR_JSQ1_0 ((uint32_t)0x00000001) /*!<Bit 0 */
#define ADC_JSQR_JSQ1_1 ((uint32_t)0x00000002) /*!<Bit 1 */
#define ADC_JSQR_JSQ1_2 ((uint32_t)0x00000004) /*!<Bit 2 */
@@ -4300,6 +4390,7 @@ typedef struct
#define TIM_CCER_CC3NP ((uint16_t)0x0800) /*!<Capture/Compare 3 Complementary output Polarity */
#define TIM_CCER_CC4E ((uint16_t)0x1000) /*!<Capture/Compare 4 output enable */
#define TIM_CCER_CC4P ((uint16_t)0x2000) /*!<Capture/Compare 4 output Polarity */
+#define TIM_CCER_CC4NP ((uint16_t)0x8000) /*!<Capture/Compare 4 Complementary output Polarity */
/******************* Bit definition for TIM_CNT register ********************/
#define TIM_CNT_CNT ((uint16_t)0xFFFF) /*!<Counter Value */
@@ -4493,6 +4584,7 @@ typedef struct
#define FSMC_BCR1_WREN ((uint32_t)0x00001000) /*!<Write enable bit */
#define FSMC_BCR1_WAITEN ((uint32_t)0x00002000) /*!<Wait enable bit */
#define FSMC_BCR1_EXTMOD ((uint32_t)0x00004000) /*!<Extended mode enable */
+#define FSMC_BCR1_ASYNCWAIT ((uint32_t)0x00008000) /*!<Asynchronous wait */
#define FSMC_BCR1_CBURSTRW ((uint32_t)0x00080000) /*!<Write burst enable */
/****************** Bit definition for FSMC_BCR2 register *******************/
@@ -4515,6 +4607,7 @@ typedef struct
#define FSMC_BCR2_WREN ((uint32_t)0x00001000) /*!<Write enable bit */
#define FSMC_BCR2_WAITEN ((uint32_t)0x00002000) /*!<Wait enable bit */
#define FSMC_BCR2_EXTMOD ((uint32_t)0x00004000) /*!<Extended mode enable */
+#define FSMC_BCR2_ASYNCWAIT ((uint32_t)0x00008000) /*!<Asynchronous wait */
#define FSMC_BCR2_CBURSTRW ((uint32_t)0x00080000) /*!<Write burst enable */
/****************** Bit definition for FSMC_BCR3 register *******************/
@@ -4537,6 +4630,7 @@ typedef struct
#define FSMC_BCR3_WREN ((uint32_t)0x00001000) /*!<Write enable bit */
#define FSMC_BCR3_WAITEN ((uint32_t)0x00002000) /*!<Wait enable bit */
#define FSMC_BCR3_EXTMOD ((uint32_t)0x00004000) /*!<Extended mode enable */
+#define FSMC_BCR3_ASYNCWAIT ((uint32_t)0x00008000) /*!<Asynchronous wait */
#define FSMC_BCR3_CBURSTRW ((uint32_t)0x00080000) /*!<Write burst enable */
/****************** Bit definition for FSMC_BCR4 register *******************/
@@ -4559,6 +4653,7 @@ typedef struct
#define FSMC_BCR4_WREN ((uint32_t)0x00001000) /*!<Write enable bit */
#define FSMC_BCR4_WAITEN ((uint32_t)0x00002000) /*!<Wait enable bit */
#define FSMC_BCR4_EXTMOD ((uint32_t)0x00004000) /*!<Extended mode enable */
+#define FSMC_BCR4_ASYNCWAIT ((uint32_t)0x00008000) /*!<Asynchronous wait */
#define FSMC_BCR4_CBURSTRW ((uint32_t)0x00080000) /*!<Write burst enable */
/****************** Bit definition for FSMC_BTR1 register ******************/
@@ -5674,7 +5769,7 @@ typedef struct
#define USB_DADDR_EF ((uint8_t)0x80) /*!<Enable Function */
-/****************** Bit definition for USB_BTABLE register ******************/
+/****************** Bit definition for USB_BTABLE register ******************/
#define USB_BTABLE_BTABLE ((uint16_t)0xFFF8) /*!<Buffer Table */
/*!<Buffer descriptor table */
@@ -6258,7 +6353,7 @@ typedef struct
#define CAN_TI2R_EXID ((uint32_t)0x001FFFF8) /*!<Extended identifier */
#define CAN_TI2R_STID ((uint32_t)0xFFE00000) /*!<Standard Identifier or Extended Identifier */
-/******************* Bit definition for CAN_TDT2R register ******************/
+/******************* Bit definition for CAN_TDT2R register ******************/
#define CAN_TDT2R_DLC ((uint32_t)0x0000000F) /*!<Data Length Code */
#define CAN_TDT2R_TGT ((uint32_t)0x00000100) /*!<Transmit Global Time */
#define CAN_TDT2R_TIME ((uint32_t)0xFFFF0000) /*!<Message Time Stamp */
@@ -7771,10 +7866,10 @@ typedef struct
#define ETH_MACCR_IFG_88Bit ((uint32_t)0x00020000) /* Minimum IFG between frames during transmission is 88Bit */
#define ETH_MACCR_IFG_80Bit ((uint32_t)0x00040000) /* Minimum IFG between frames during transmission is 80Bit */
#define ETH_MACCR_IFG_72Bit ((uint32_t)0x00060000) /* Minimum IFG between frames during transmission is 72Bit */
- #define ETH_MACCR_IFG_64Bit ((uint32_t)0x00080000) /* Minimum IFG between frames during transmission is 64Bit */
+ #define ETH_MACCR_IFG_64Bit ((uint32_t)0x00080000) /* Minimum IFG between frames during transmission is 64Bit */
#define ETH_MACCR_IFG_56Bit ((uint32_t)0x000A0000) /* Minimum IFG between frames during transmission is 56Bit */
#define ETH_MACCR_IFG_48Bit ((uint32_t)0x000C0000) /* Minimum IFG between frames during transmission is 48Bit */
- #define ETH_MACCR_IFG_40Bit ((uint32_t)0x000E0000) /* Minimum IFG between frames during transmission is 40Bit */
+ #define ETH_MACCR_IFG_40Bit ((uint32_t)0x000E0000) /* Minimum IFG between frames during transmission is 40Bit */
#define ETH_MACCR_CSD ((uint32_t)0x00010000) /* Carrier sense disable (during transmission) */
#define ETH_MACCR_FES ((uint32_t)0x00004000) /* Fast ethernet speed */
#define ETH_MACCR_ROD ((uint32_t)0x00002000) /* Receive own disable */
@@ -7788,24 +7883,24 @@ typedef struct
#define ETH_MACCR_BL_10 ((uint32_t)0x00000000) /* k = min (n, 10) */
#define ETH_MACCR_BL_8 ((uint32_t)0x00000020) /* k = min (n, 8) */
#define ETH_MACCR_BL_4 ((uint32_t)0x00000040) /* k = min (n, 4) */
- #define ETH_MACCR_BL_1 ((uint32_t)0x00000060) /* k = min (n, 1) */
+ #define ETH_MACCR_BL_1 ((uint32_t)0x00000060) /* k = min (n, 1) */
#define ETH_MACCR_DC ((uint32_t)0x00000010) /* Defferal check */
#define ETH_MACCR_TE ((uint32_t)0x00000008) /* Transmitter enable */
#define ETH_MACCR_RE ((uint32_t)0x00000004) /* Receiver enable */
/* Bit definition for Ethernet MAC Frame Filter Register */
-#define ETH_MACFFR_RA ((uint32_t)0x80000000) /* Receive all */
-#define ETH_MACFFR_HPF ((uint32_t)0x00000400) /* Hash or perfect filter */
-#define ETH_MACFFR_SAF ((uint32_t)0x00000200) /* Source address filter enable */
-#define ETH_MACFFR_SAIF ((uint32_t)0x00000100) /* SA inverse filtering */
+#define ETH_MACFFR_RA ((uint32_t)0x80000000) /* Receive all */
+#define ETH_MACFFR_HPF ((uint32_t)0x00000400) /* Hash or perfect filter */
+#define ETH_MACFFR_SAF ((uint32_t)0x00000200) /* Source address filter enable */
+#define ETH_MACFFR_SAIF ((uint32_t)0x00000100) /* SA inverse filtering */
#define ETH_MACFFR_PCF ((uint32_t)0x000000C0) /* Pass control frames: 3 cases */
#define ETH_MACFFR_PCF_BlockAll ((uint32_t)0x00000040) /* MAC filters all control frames from reaching the application */
#define ETH_MACFFR_PCF_ForwardAll ((uint32_t)0x00000080) /* MAC forwards all control frames to application even if they fail the Address Filter */
- #define ETH_MACFFR_PCF_ForwardPassedAddrFilter ((uint32_t)0x000000C0) /* MAC forwards control frames that pass the Address Filter. */
-#define ETH_MACFFR_BFD ((uint32_t)0x00000020) /* Broadcast frame disable */
-#define ETH_MACFFR_PAM ((uint32_t)0x00000010) /* Pass all mutlicast */
-#define ETH_MACFFR_DAIF ((uint32_t)0x00000008) /* DA Inverse filtering */
-#define ETH_MACFFR_HM ((uint32_t)0x00000004) /* Hash multicast */
+ #define ETH_MACFFR_PCF_ForwardPassedAddrFilter ((uint32_t)0x000000C0) /* MAC forwards control frames that pass the Address Filter. */
+#define ETH_MACFFR_BFD ((uint32_t)0x00000020) /* Broadcast frame disable */
+#define ETH_MACFFR_PAM ((uint32_t)0x00000010) /* Pass all mutlicast */
+#define ETH_MACFFR_DAIF ((uint32_t)0x00000008) /* DA Inverse filtering */
+#define ETH_MACFFR_HM ((uint32_t)0x00000004) /* Hash multicast */
#define ETH_MACFFR_HU ((uint32_t)0x00000002) /* Hash unicast */
#define ETH_MACFFR_PM ((uint32_t)0x00000001) /* Promiscuous mode */
@@ -7816,15 +7911,15 @@ typedef struct
#define ETH_MACHTLR_HTL ((uint32_t)0xFFFFFFFF) /* Hash table low */
/* Bit definition for Ethernet MAC MII Address Register */
-#define ETH_MACMIIAR_PA ((uint32_t)0x0000F800) /* Physical layer address */
-#define ETH_MACMIIAR_MR ((uint32_t)0x000007C0) /* MII register in the selected PHY */
-#define ETH_MACMIIAR_CR ((uint32_t)0x0000001C) /* CR clock range: 6 cases */
+#define ETH_MACMIIAR_PA ((uint32_t)0x0000F800) /* Physical layer address */
+#define ETH_MACMIIAR_MR ((uint32_t)0x000007C0) /* MII register in the selected PHY */
+#define ETH_MACMIIAR_CR ((uint32_t)0x0000001C) /* CR clock range: 6 cases */
#define ETH_MACMIIAR_CR_Div42 ((uint32_t)0x00000000) /* HCLK:60-72 MHz; MDC clock= HCLK/42 */
#define ETH_MACMIIAR_CR_Div16 ((uint32_t)0x00000008) /* HCLK:20-35 MHz; MDC clock= HCLK/16 */
#define ETH_MACMIIAR_CR_Div26 ((uint32_t)0x0000000C) /* HCLK:35-60 MHz; MDC clock= HCLK/26 */
-#define ETH_MACMIIAR_MW ((uint32_t)0x00000002) /* MII write */
-#define ETH_MACMIIAR_MB ((uint32_t)0x00000001) /* MII busy */
-
+#define ETH_MACMIIAR_MW ((uint32_t)0x00000002) /* MII write */
+#define ETH_MACMIIAR_MB ((uint32_t)0x00000001) /* MII busy */
+
/* Bit definition for Ethernet MAC MII Data Register */
#define ETH_MACMIIDR_MD ((uint32_t)0x0000FFFF) /* MII data: read/write data from/to PHY */
@@ -7835,7 +7930,7 @@ typedef struct
#define ETH_MACFCR_PLT_Minus4 ((uint32_t)0x00000000) /* Pause time minus 4 slot times */
#define ETH_MACFCR_PLT_Minus28 ((uint32_t)0x00000010) /* Pause time minus 28 slot times */
#define ETH_MACFCR_PLT_Minus144 ((uint32_t)0x00000020) /* Pause time minus 144 slot times */
- #define ETH_MACFCR_PLT_Minus256 ((uint32_t)0x00000030) /* Pause time minus 256 slot times */
+ #define ETH_MACFCR_PLT_Minus256 ((uint32_t)0x00000030) /* Pause time minus 256 slot times */
#define ETH_MACFCR_UPFD ((uint32_t)0x00000008) /* Unicast pause frame detect */
#define ETH_MACFCR_RFCE ((uint32_t)0x00000004) /* Receive flow control enable */
#define ETH_MACFCR_TFCE ((uint32_t)0x00000002) /* Transmit flow control enable */
@@ -7845,7 +7940,7 @@ typedef struct
#define ETH_MACVLANTR_VLANTC ((uint32_t)0x00010000) /* 12-bit VLAN tag comparison */
#define ETH_MACVLANTR_VLANTI ((uint32_t)0x0000FFFF) /* VLAN tag identifier (for receive frames) */
-/* Bit definition for Ethernet MAC Remote Wake-UpFrame Filter Register */
+/* Bit definition for Ethernet MAC Remote Wake-UpFrame Filter Register */
#define ETH_MACRWUFFR_D ((uint32_t)0xFFFFFFFF) /* Wake-up frame filter register data */
/* Eight sequential Writes to this address (offset 0x28) will write all Wake-UpFrame Filter Registers.
Eight sequential Reads from this address (offset 0x28) will read all Wake-UpFrame Filter Registers. */
@@ -7853,13 +7948,13 @@ typedef struct
Wake-UpFrame Filter Reg1 : Filter 1 Byte Mask
Wake-UpFrame Filter Reg2 : Filter 2 Byte Mask
Wake-UpFrame Filter Reg3 : Filter 3 Byte Mask
- Wake-UpFrame Filter Reg4 : RSVD - Filter3 Command - RSVD - Filter2 Command -
+ Wake-UpFrame Filter Reg4 : RSVD - Filter3 Command - RSVD - Filter2 Command -
RSVD - Filter1 Command - RSVD - Filter0 Command
Wake-UpFrame Filter Re5 : Filter3 Offset - Filter2 Offset - Filter1 Offset - Filter0 Offset
Wake-UpFrame Filter Re6 : Filter1 CRC16 - Filter0 CRC16
Wake-UpFrame Filter Re7 : Filter3 CRC16 - Filter2 CRC16 */
-/* Bit definition for Ethernet MAC PMT Control and Status Register */
+/* Bit definition for Ethernet MAC PMT Control and Status Register */
#define ETH_MACPMTCSR_WFFRPR ((uint32_t)0x80000000) /* Wake-Up Frame Filter Register Pointer Reset */
#define ETH_MACPMTCSR_GU ((uint32_t)0x00000200) /* Global Unicast */
#define ETH_MACPMTCSR_WFR ((uint32_t)0x00000040) /* Wake-Up Frame Received */
@@ -7894,7 +7989,7 @@ typedef struct
#define ETH_MACA1HR_MBC_LBits31_24 ((uint32_t)0x08000000) /* Mask MAC Address low reg bits [31:24] */
#define ETH_MACA1HR_MBC_LBits23_16 ((uint32_t)0x04000000) /* Mask MAC Address low reg bits [23:16] */
#define ETH_MACA1HR_MBC_LBits15_8 ((uint32_t)0x02000000) /* Mask MAC Address low reg bits [15:8] */
- #define ETH_MACA1HR_MBC_LBits7_0 ((uint32_t)0x01000000) /* Mask MAC Address low reg bits [7:0] */
+ #define ETH_MACA1HR_MBC_LBits7_0 ((uint32_t)0x01000000) /* Mask MAC Address low reg bits [7:0] */
#define ETH_MACA1HR_MACA1H ((uint32_t)0x0000FFFF) /* MAC address1 high */
/* Bit definition for Ethernet MAC Address1 Low Register */
@@ -8030,26 +8125,26 @@ typedef struct
#define ETH_DMABMR_RDP_4Beat ((uint32_t)0x00080000) /* maximum number of beats to be transferred in one RxDMA transaction is 4 */
#define ETH_DMABMR_RDP_8Beat ((uint32_t)0x00100000) /* maximum number of beats to be transferred in one RxDMA transaction is 8 */
#define ETH_DMABMR_RDP_16Beat ((uint32_t)0x00200000) /* maximum number of beats to be transferred in one RxDMA transaction is 16 */
- #define ETH_DMABMR_RDP_32Beat ((uint32_t)0x00400000) /* maximum number of beats to be transferred in one RxDMA transaction is 32 */
+ #define ETH_DMABMR_RDP_32Beat ((uint32_t)0x00400000) /* maximum number of beats to be transferred in one RxDMA transaction is 32 */
#define ETH_DMABMR_RDP_4xPBL_4Beat ((uint32_t)0x01020000) /* maximum number of beats to be transferred in one RxDMA transaction is 4 */
#define ETH_DMABMR_RDP_4xPBL_8Beat ((uint32_t)0x01040000) /* maximum number of beats to be transferred in one RxDMA transaction is 8 */
#define ETH_DMABMR_RDP_4xPBL_16Beat ((uint32_t)0x01080000) /* maximum number of beats to be transferred in one RxDMA transaction is 16 */
#define ETH_DMABMR_RDP_4xPBL_32Beat ((uint32_t)0x01100000) /* maximum number of beats to be transferred in one RxDMA transaction is 32 */
#define ETH_DMABMR_RDP_4xPBL_64Beat ((uint32_t)0x01200000) /* maximum number of beats to be transferred in one RxDMA transaction is 64 */
- #define ETH_DMABMR_RDP_4xPBL_128Beat ((uint32_t)0x01400000) /* maximum number of beats to be transferred in one RxDMA transaction is 128 */
+ #define ETH_DMABMR_RDP_4xPBL_128Beat ((uint32_t)0x01400000) /* maximum number of beats to be transferred in one RxDMA transaction is 128 */
#define ETH_DMABMR_FB ((uint32_t)0x00010000) /* Fixed Burst */
#define ETH_DMABMR_RTPR ((uint32_t)0x0000C000) /* Rx Tx priority ratio */
#define ETH_DMABMR_RTPR_1_1 ((uint32_t)0x00000000) /* Rx Tx priority ratio */
#define ETH_DMABMR_RTPR_2_1 ((uint32_t)0x00004000) /* Rx Tx priority ratio */
#define ETH_DMABMR_RTPR_3_1 ((uint32_t)0x00008000) /* Rx Tx priority ratio */
- #define ETH_DMABMR_RTPR_4_1 ((uint32_t)0x0000C000) /* Rx Tx priority ratio */
+ #define ETH_DMABMR_RTPR_4_1 ((uint32_t)0x0000C000) /* Rx Tx priority ratio */
#define ETH_DMABMR_PBL ((uint32_t)0x00003F00) /* Programmable burst length */
#define ETH_DMABMR_PBL_1Beat ((uint32_t)0x00000100) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 1 */
#define ETH_DMABMR_PBL_2Beat ((uint32_t)0x00000200) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 2 */
#define ETH_DMABMR_PBL_4Beat ((uint32_t)0x00000400) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
#define ETH_DMABMR_PBL_8Beat ((uint32_t)0x00000800) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
#define ETH_DMABMR_PBL_16Beat ((uint32_t)0x00001000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
- #define ETH_DMABMR_PBL_32Beat ((uint32_t)0x00002000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
+ #define ETH_DMABMR_PBL_32Beat ((uint32_t)0x00002000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
#define ETH_DMABMR_PBL_4xPBL_4Beat ((uint32_t)0x01000100) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
#define ETH_DMABMR_PBL_4xPBL_8Beat ((uint32_t)0x01000200) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
#define ETH_DMABMR_PBL_4xPBL_16Beat ((uint32_t)0x01000400) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
@@ -8179,7 +8274,7 @@ typedef struct
/**
* @}
- */
+ */
#ifdef USE_STDPERIPH_DRIVER
#include "stm32f10x_conf.h"
diff --git a/os/hal/platforms/STM32/uart_lld.c b/os/hal/platforms/STM32/uart_lld.c
index 9769aa090..e2f306302 100644
--- a/os/hal/platforms/STM32/uart_lld.c
+++ b/os/hal/platforms/STM32/uart_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -90,13 +91,13 @@ static void set_rx_idle_loop(UARTDriver *uartp) {
/* RX DMA channel preparation, if the char callback is defined then the
TCIE interrupt is enabled too.*/
- if (uartp->ud_config->uc_rxchar == NULL)
+ if (uartp->config->rxchar_cb == NULL)
ccr = DMA_CCR1_CIRC | DMA_CCR1_TEIE;
else
ccr = DMA_CCR1_CIRC | DMA_CCR1_TEIE | DMA_CCR1_TCIE;
- dmaSetupChannel(uartp->ud_dmap, uartp->ud_dmarx, 1,
- &uartp->ud_rxbuf, uartp->ud_dmaccr | ccr);
- dmaEnableChannel(uartp->ud_dmap, uartp->ud_dmarx);
+ dmaSetupChannel(uartp->dmap, uartp->dmarx, 1,
+ &uartp->rxbuf, uartp->dmaccr | ccr);
+ dmaEnableChannel(uartp->dmap, uartp->dmarx);
}
/**
@@ -108,15 +109,15 @@ static void set_rx_idle_loop(UARTDriver *uartp) {
static void usart_stop(UARTDriver *uartp) {
/* Stops RX and TX DMA channels.*/
- dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmarx);
- dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmatx);
- dmaClearChannel(uartp->ud_dmap, uartp->ud_dmarx);
- dmaClearChannel(uartp->ud_dmap, uartp->ud_dmatx);
+ dmaDisableChannel(uartp->dmap, uartp->dmarx);
+ dmaDisableChannel(uartp->dmap, uartp->dmatx);
+ dmaClearChannel(uartp->dmap, uartp->dmarx);
+ dmaClearChannel(uartp->dmap, uartp->dmatx);
/* Stops USART operations.*/
- uartp->ud_usart->CR1 = 0;
- uartp->ud_usart->CR2 = 0;
- uartp->ud_usart->CR3 = 0;
+ uartp->usart->CR1 = 0;
+ uartp->usart->CR2 = 0;
+ uartp->usart->CR3 = 0;
}
/**
@@ -127,16 +128,16 @@ static void usart_stop(UARTDriver *uartp) {
*/
static void usart_start(UARTDriver *uartp) {
uint16_t cr1;
- USART_TypeDef *u = uartp->ud_usart;
+ USART_TypeDef *u = uartp->usart;
/* Defensive programming, starting from a clean state.*/
usart_stop(uartp);
/* Baud rate setting.*/
- if (uartp->ud_usart == USART1)
- u->BRR = STM32_PCLK2 / uartp->ud_config->uc_speed;
+ if (uartp->usart == USART1)
+ u->BRR = STM32_PCLK2 / uartp->config->speed;
else
- u->BRR = STM32_PCLK1 / uartp->ud_config->uc_speed;
+ u->BRR = STM32_PCLK1 / uartp->config->speed;
/* Resetting eventual pending status flags.*/
(void)u->SR; /* SR reset step 1.*/
@@ -145,14 +146,14 @@ static void usart_start(UARTDriver *uartp) {
/* Note that some bits are enforced because required for correct driver
operations.*/
- if (uartp->ud_config->uc_txend2 == NULL)
+ if (uartp->config->txend2_cb == NULL)
cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE;
else
cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE |
USART_CR1_TCIE;
- u->CR1 = uartp->ud_config->uc_cr1 | cr1;
- u->CR2 = uartp->ud_config->uc_cr2 | USART_CR2_LBDIE;
- u->CR3 = uartp->ud_config->uc_cr3 | USART_CR3_DMAT | USART_CR3_DMAR |
+ u->CR1 = uartp->config->cr1 | cr1;
+ u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE;
+ u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR |
USART_CR3_EIE;
/* Starting the receiver idle loop.*/
@@ -163,17 +164,38 @@ static void usart_start(UARTDriver *uartp) {
* @brief RX DMA common service routine.
*
* @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-static void serve_rx_end_irq(UARTDriver *uartp) {
+static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) {
- uartp->ud_rxstate = UART_RX_COMPLETE;
- if (uartp->ud_config->uc_rxend != NULL)
- uartp->ud_config->uc_rxend(uartp);
- /* If the callback didn't explicitly change state then the receiver
- automatically returns to the idle state.*/
- if (uartp->ud_rxstate == UART_RX_COMPLETE) {
- uartp->ud_rxstate = UART_RX_IDLE;
- set_rx_idle_loop(uartp);
+ /* DMA errors handling.*/
+#if defined(STM32_UART_DMA_ERROR_HOOK)
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_UART_DMA_ERROR_HOOK(uartp);
+ }
+#else
+ (void)flags;
+#endif
+
+ if (uartp->rxstate == UART_RX_IDLE) {
+ /* Receiver in idle state, a callback is generated, if enabled, for each
+ received character and then the driver stays in the same state.*/
+ if (uartp->config->rxchar_cb != NULL)
+ uartp->config->rxchar_cb(uartp, uartp->rxbuf);
+ }
+ else {
+ /* Receiver in active state, a callback is generated, if enabled, after
+ a completed transfer.*/
+ dmaDisableChannel(uartp->dmap, uartp->dmarx);
+ uartp->rxstate = UART_RX_COMPLETE;
+ if (uartp->config->rxend_cb != NULL)
+ uartp->config->rxend_cb(uartp);
+ /* If the callback didn't explicitly change state then the receiver
+ automatically returns to the idle state.*/
+ if (uartp->rxstate == UART_RX_COMPLETE) {
+ uartp->rxstate = UART_RX_IDLE;
+ set_rx_idle_loop(uartp);
+ }
}
}
@@ -181,18 +203,30 @@ static void serve_rx_end_irq(UARTDriver *uartp) {
* @brief TX DMA common service routine.
*
* @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-static void serve_tx_end_irq(UARTDriver *uartp) {
+static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_UART_DMA_ERROR_HOOK)
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_UART_DMA_ERROR_HOOK(uartp);
+ }
+#else
+ (void)flags;
+#endif
+ dmaDisableChannel(uartp->dmap, uartp->dmatx);
/* A callback is generated, if enabled, after a completed transfer.*/
- uartp->ud_txstate = UART_TX_COMPLETE;
- if (uartp->ud_config->uc_txend1 != NULL)
- uartp->ud_config->uc_txend1(uartp);
+ uartp->txstate = UART_TX_COMPLETE;
+ if (uartp->config->txend1_cb != NULL)
+ uartp->config->txend1_cb(uartp);
/* If the callback didn't explicitly change state then the transmitter
automatically returns to the idle state.*/
- if (uartp->ud_txstate == UART_TX_COMPLETE)
- uartp->ud_txstate = UART_TX_IDLE;
+ if (uartp->txstate == UART_TX_COMPLETE)
+ uartp->txstate = UART_TX_IDLE;
}
+
/**
* @brief USART common service routine.
*
@@ -200,21 +234,21 @@ static void serve_tx_end_irq(UARTDriver *uartp) {
*/
static void serve_usart_irq(UARTDriver *uartp) {
uint16_t sr;
- USART_TypeDef *u = uartp->ud_usart;
+ USART_TypeDef *u = uartp->usart;
sr = u->SR; /* SR reset step 1.*/
(void)u->DR; /* SR reset step 2.*/
if (sr & (USART_SR_LBD | USART_SR_ORE | USART_SR_NE |
USART_SR_FE | USART_SR_PE)) {
u->SR = ~USART_SR_LBD;
- if (uartp->ud_config->uc_rxerr != NULL)
- uartp->ud_config->uc_rxerr(uartp, translate_errors(sr));
+ if (uartp->config->rxerr_cb != NULL)
+ uartp->config->rxerr_cb(uartp, translate_errors(sr));
}
if (sr & USART_SR_TC) {
u->SR = ~USART_SR_TC;
/* End of transmission, a callback is generated.*/
- if (uartp->ud_config->uc_txend2 != NULL)
- uartp->ud_config->uc_txend2(uartp);
+ if (uartp->config->txend2_cb != NULL)
+ uartp->config->txend2_cb(uartp);
}
}
@@ -224,58 +258,6 @@ static void serve_usart_irq(UARTDriver *uartp) {
#if STM32_UART_USE_USART1 || defined(__DOXYGEN__)
/**
- * @brief USART1 RX DMA interrupt handler (channel 5).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
- UARTDriver *uartp;
-
- CH_IRQ_PROLOGUE();
-
- uartp = &UARTD1;
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF5) != 0) {
- STM32_UART_USART1_DMA_ERROR_HOOK();
- }
- if (uartp->ud_rxstate == UART_RX_IDLE) {
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
- /* Fast IRQ path, this is why it is not centralized in serve_rx_end_irq().*/
- /* Receiver in idle state, a callback is generated, if enabled, for each
- received character and then the driver stays in the same state.*/
- if (uartp->ud_config->uc_rxchar != NULL)
- uartp->ud_config->uc_rxchar(uartp, uartp->ud_rxbuf);
- }
- else {
- /* Receiver in active state, a callback is generated, if enabled, after
- a completed transfer.*/
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
- serve_rx_end_irq(uartp);
- }
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief USART1 TX DMA interrupt handler (channel 4).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF4) != 0) {
- STM32_UART_USART1_DMA_ERROR_HOOK();
- }
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
- serve_tx_end_irq(&UARTD1);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
* @brief USART1 IRQ handler.
*
* @isr
@@ -292,58 +274,6 @@ CH_IRQ_HANDLER(USART1_IRQHandler) {
#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
/**
- * @brief USART2 RX DMA interrupt handler (channel 6).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) {
- UARTDriver *uartp;
-
- CH_IRQ_PROLOGUE();
-
- uartp = &UARTD2;
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF6) != 0) {
- STM32_UART_USART2_DMA_ERROR_HOOK();
- }
- if (uartp->ud_rxstate == UART_RX_IDLE) {
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
- /* Fast IRQ path, this is why it is not centralized in serve_rx_end_irq().*/
- /* Receiver in idle state, a callback is generated, if enabled, for each
- received character and then the driver stays in the same state.*/
- if (uartp->ud_config->uc_rxchar != NULL)
- uartp->ud_config->uc_rxchar(uartp, uartp->ud_rxbuf);
- }
- else {
- /* Receiver in active state, a callback is generated, if enabled, after
- a completed transfer.*/
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
- serve_rx_end_irq(uartp);
- }
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief USART2 TX DMA interrupt handler (channel 7).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF7) != 0) {
- STM32_UART_USART2_DMA_ERROR_HOOK();
- }
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
- serve_tx_end_irq(&UARTD2);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
* @brief USART2 IRQ handler.
*
* @isr
@@ -360,58 +290,6 @@ CH_IRQ_HANDLER(USART2_IRQHandler) {
#if STM32_UART_USE_USART3 || defined(__DOXYGEN__)
/**
- * @brief USART3 RX DMA interrupt handler (channel 3).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
- UARTDriver *uartp;
-
- CH_IRQ_PROLOGUE();
-
- uartp = &UARTD3;
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF3) != 0) {
- STM32_UART_USART1_DMA_ERROR_HOOK();
- }
- if (uartp->ud_rxstate == UART_RX_IDLE) {
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
- /* Fast IRQ path, this is why it is not centralized in serve_rx_end_irq().*/
- /* Receiver in idle state, a callback is generated, if enabled, for each
- received character and then the driver stays in the same state.*/
- if (uartp->ud_config->uc_rxchar != NULL)
- uartp->ud_config->uc_rxchar(uartp, uartp->ud_rxbuf);
- }
- else {
- /* Receiver in active state, a callback is generated, if enabled, after
- a completed transfer.*/
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
- serve_rx_end_irq(uartp);
- }
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief USART3 TX DMA interrupt handler (channel 2).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF2) != 0) {
- STM32_UART_USART1_DMA_ERROR_HOOK();
- }
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
- serve_tx_end_irq(&UARTD3);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
* @brief USART3 IRQ handler.
*
* @isr
@@ -438,36 +316,30 @@ CH_IRQ_HANDLER(USART3_IRQHandler) {
void uart_lld_init(void) {
#if STM32_UART_USE_USART1
- RCC->APB2RSTR = RCC_APB2RSTR_USART1RST;
- RCC->APB2RSTR = 0;
uartObjectInit(&UARTD1);
- UARTD1.ud_usart = USART1;
- UARTD1.ud_dmap = STM32_DMA1;
- UARTD1.ud_dmarx = STM32_DMA_CHANNEL_5;
- UARTD1.ud_dmatx = STM32_DMA_CHANNEL_4;
- UARTD1.ud_dmaccr = 0;
+ UARTD1.usart = USART1;
+ UARTD1.dmap = STM32_DMA1;
+ UARTD1.dmarx = STM32_DMA_CHANNEL_5;
+ UARTD1.dmatx = STM32_DMA_CHANNEL_4;
+ UARTD1.dmaccr = 0;
#endif
#if STM32_UART_USE_USART2
- RCC->APB1RSTR = RCC_APB1RSTR_USART2RST;
- RCC->APB1RSTR = 0;
uartObjectInit(&UARTD2);
- UARTD2.ud_usart = USART2;
- UARTD2.ud_dmap = STM32_DMA1;
- UARTD2.ud_dmarx = STM32_DMA_CHANNEL_6;
- UARTD2.ud_dmatx = STM32_DMA_CHANNEL_7;
- UARTD2.ud_dmaccr = 0;
+ UARTD2.usart = USART2;
+ UARTD2.dmap = STM32_DMA1;
+ UARTD2.dmarx = STM32_DMA_CHANNEL_6;
+ UARTD2.dmatx = STM32_DMA_CHANNEL_7;
+ UARTD2.dmaccr = 0;
#endif
#if STM32_UART_USE_USART3
- RCC->APB1RSTR = RCC_APB1RSTR_USART3RST;
- RCC->APB1RSTR = 0;
uartObjectInit(&UARTD3);
- UARTD3.ud_usart = USART3;
- UARTD3.ud_dmap = STM32_DMA1;
- UARTD3.ud_dmarx = STM32_DMA_CHANNEL_3;
- UARTD3.ud_dmatx = STM32_DMA_CHANNEL_2;
- UARTD3.ud_dmaccr = 0;
+ UARTD3.usart = USART3;
+ UARTD3.dmap = STM32_DMA1;
+ UARTD3.dmarx = STM32_DMA_CHANNEL_3;
+ UARTD3.dmatx = STM32_DMA_CHANNEL_2;
+ UARTD3.dmaccr = 0;
#endif
}
@@ -480,10 +352,14 @@ void uart_lld_init(void) {
*/
void uart_lld_start(UARTDriver *uartp) {
- if (uartp->ud_state == UART_STOP) {
+ if (uartp->state == UART_STOP) {
#if STM32_UART_USE_USART1
if (&UARTD1 == uartp) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp);
NVICEnableVector(USART1_IRQn,
CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel4_IRQn,
@@ -496,7 +372,11 @@ void uart_lld_start(UARTDriver *uartp) {
#if STM32_UART_USE_USART2
if (&UARTD2 == uartp) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_6,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_7,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp);
NVICEnableVector(USART2_IRQn,
CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel6_IRQn,
@@ -509,7 +389,11 @@ void uart_lld_start(UARTDriver *uartp) {
#if STM32_UART_USE_USART3
if (&UARTD3 == uartp) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp);
NVICEnableVector(USART3_IRQn,
CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel2_IRQn,
@@ -522,18 +406,18 @@ void uart_lld_start(UARTDriver *uartp) {
/* Static DMA setup, the transfer size depends on the USART settings,
it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/
- uartp->ud_dmaccr = STM32_UART_USART1_DMA_PRIORITY << 12;
- if ((uartp->ud_config->uc_cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M)
- uartp->ud_dmaccr |= DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0;
- dmaChannelSetPeripheral(&uartp->ud_dmap->channels[uartp->ud_dmarx],
- &uartp->ud_usart->DR);
- dmaChannelSetPeripheral(&uartp->ud_dmap->channels[uartp->ud_dmatx],
- &uartp->ud_usart->DR);
- uartp->ud_rxbuf = 0;
+ uartp->dmaccr = STM32_UART_USART1_DMA_PRIORITY << 12;
+ if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M)
+ uartp->dmaccr |= DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0;
+ dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmarx],
+ &uartp->usart->DR);
+ dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmatx],
+ &uartp->usart->DR);
+ uartp->rxbuf = 0;
}
- uartp->ud_rxstate = UART_RX_IDLE;
- uartp->ud_txstate = UART_TX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
+ uartp->txstate = UART_TX_IDLE;
usart_start(uartp);
}
@@ -546,7 +430,7 @@ void uart_lld_start(UARTDriver *uartp) {
*/
void uart_lld_stop(UARTDriver *uartp) {
- if (uartp->ud_state == UART_READY) {
+ if (uartp->state == UART_READY) {
usart_stop(uartp);
#if STM32_UART_USE_USART1
@@ -554,7 +438,8 @@ void uart_lld_stop(UARTDriver *uartp) {
NVICDisableVector(USART1_IRQn);
NVICDisableVector(DMA1_Channel4_IRQn);
NVICDisableVector(DMA1_Channel5_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5);
RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN;
return;
}
@@ -565,7 +450,8 @@ void uart_lld_stop(UARTDriver *uartp) {
NVICDisableVector(USART2_IRQn);
NVICDisableVector(DMA1_Channel6_IRQn);
NVICDisableVector(DMA1_Channel7_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_6);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_7);
RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN;
return;
}
@@ -576,7 +462,8 @@ void uart_lld_stop(UARTDriver *uartp) {
NVICDisableVector(USART3_IRQn);
NVICDisableVector(DMA1_Channel2_IRQn);
NVICDisableVector(DMA1_Channel3_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3);
RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN;
return;
}
@@ -598,10 +485,10 @@ void uart_lld_stop(UARTDriver *uartp) {
void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
/* TX DMA channel preparation and start.*/
- dmaSetupChannel(uartp->ud_dmap, uartp->ud_dmatx, n, txbuf,
- uartp->ud_dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
+ dmaSetupChannel(uartp->dmap, uartp->dmatx, n, txbuf,
+ uartp->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC |
DMA_CCR1_TEIE | DMA_CCR1_TCIE);
- dmaEnableChannel(uartp->ud_dmap, uartp->ud_dmatx);
+ dmaEnableChannel(uartp->dmap, uartp->dmatx);
}
/**
@@ -617,9 +504,9 @@ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
*/
size_t uart_lld_stop_send(UARTDriver *uartp) {
- dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmatx);
- dmaClearChannel(uartp->ud_dmap, uartp->ud_dmatx);
- return (size_t)uartp->ud_dmap->channels[uartp->ud_dmatx].CNDTR;
+ dmaDisableChannel(uartp->dmap, uartp->dmatx);
+ dmaClearChannel(uartp->dmap, uartp->dmatx);
+ return (size_t)uartp->dmap->channels[uartp->dmatx].CNDTR;
}
/**
@@ -636,14 +523,14 @@ size_t uart_lld_stop_send(UARTDriver *uartp) {
void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
/* Stopping previous activity (idle state).*/
- dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmarx);
- dmaClearChannel(uartp->ud_dmap, uartp->ud_dmarx);
+ dmaDisableChannel(uartp->dmap, uartp->dmarx);
+ dmaClearChannel(uartp->dmap, uartp->dmarx);
/* RX DMA channel preparation and start.*/
- dmaSetupChannel(uartp->ud_dmap, uartp->ud_dmarx, n, rxbuf,
- uartp->ud_dmaccr | DMA_CCR1_MINC |
+ dmaSetupChannel(uartp->dmap, uartp->dmarx, n, rxbuf,
+ uartp->dmaccr | DMA_CCR1_MINC |
DMA_CCR1_TEIE | DMA_CCR1_TCIE);
- dmaEnableChannel(uartp->ud_dmap, uartp->ud_dmarx);
+ dmaEnableChannel(uartp->dmap, uartp->dmarx);
}
/**
@@ -660,9 +547,9 @@ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
size_t uart_lld_stop_receive(UARTDriver *uartp) {
size_t n;
- dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmarx);
- dmaClearChannel(uartp->ud_dmap, uartp->ud_dmarx);
- n = (size_t)uartp->ud_dmap->channels[uartp->ud_dmarx].CNDTR;
+ dmaDisableChannel(uartp->dmap, uartp->dmarx);
+ dmaClearChannel(uartp->dmap, uartp->dmarx);
+ n = (size_t)uartp->dmap->channels[uartp->dmarx].CNDTR;
set_rx_idle_loop(uartp);
return n;
}
diff --git a/os/hal/platforms/STM32/uart_lld.h b/os/hal/platforms/STM32/uart_lld.h
index 589a274fa..9321df85c 100644
--- a/os/hal/platforms/STM32/uart_lld.h
+++ b/os/hal/platforms/STM32/uart_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -68,21 +69,21 @@
/**
* @brief USART1 interrupt priority level setting.
*/
-#if !defined(STM32_UART_USART1_IRQ_PRIO) || defined(__DOXYGEN__)
+#if !defined(STM32_UART_USART1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_UART_USART1_IRQ_PRIORITY 12
#endif
/**
* @brief USART2 interrupt priority level setting.
*/
-#if !defined(STM32_UART_USART2_IRQ_PRIO) || defined(__DOXYGEN__)
+#if !defined(STM32_UART_USART2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_UART_USART2_IRQ_PRIORITY 12
#endif
/**
* @brief USART3 interrupt priority level setting.
*/
-#if !defined(STM32_UART_USART3_IRQ_PRIO) || defined(__DOXYGEN__)
+#if !defined(STM32_UART_USART3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_UART_USART3_IRQ_PRIORITY 12
#endif
@@ -92,7 +93,7 @@
* because of the channels ordering the RX channel has always priority
* over the TX channel.
*/
-#if !defined(STM32_UART_USART1_DMA_PRIO) || defined(__DOXYGEN__)
+#if !defined(STM32_UART_USART1_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_UART_USART1_DMA_PRIORITY 0
#endif
@@ -102,7 +103,7 @@
* because of the channels ordering the RX channel has always priority
* over the TX channel.
*/
-#if !defined(STM32_UART_USART2_DMA_PRIO) || defined(__DOXYGEN__)
+#if !defined(STM32_UART_USART2_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_UART_USART2_DMA_PRIORITY 0
#endif
/**
@@ -111,35 +112,17 @@
* because of the channels ordering the RX channel has always priority
* over the TX channel.
*/
-#if !defined(STM32_UART_USART3_DMA_PRIO) || defined(__DOXYGEN__)
+#if !defined(STM32_UART_USART3_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_UART_USART3_DMA_PRIORITY 0
#endif
/**
* @brief USART1 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
*/
-#if !defined(STM32_UART_USART1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#endif
-
-/**
- * @brief USART2 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
- */
-#if !defined(STM32_UART_USART2_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#endif
-
-/**
- * @brief USART3 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
- */
-#if !defined(STM32_UART_USART3_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#if !defined(STM32_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
#endif
/*===========================================================================*/
@@ -158,15 +141,15 @@
#error "USART3 not present in the selected device"
#endif
-#if STM32_UART_USE_UART4 && !STM32_HAS_UART4
-#error "UART4 not present in the selected device"
-#endif
-
#if !STM32_UART_USE_USART1 && !STM32_UART_USE_USART2 && \
- !STM32_UART_USE_USART3 && !STM32_UART_USE_UART4
+ !STM32_UART_USE_USART3
#error "UART driver activated but no USART/UART peripheral assigned"
#endif
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -212,40 +195,40 @@ typedef struct {
/**
* @brief End of transmission buffer callback.
*/
- uartcb_t uc_txend1;
+ uartcb_t txend1_cb;
/**
* @brief Physical end of transmission callback.
*/
- uartcb_t uc_txend2;
+ uartcb_t txend2_cb;
/**
* @brief Receive buffer filled callback.
*/
- uartcb_t uc_rxend;
+ uartcb_t rxend_cb;
/**
* @brief Character received while out if the @p UART_RECEIVE state.
*/
- uartccb_t uc_rxchar;
+ uartccb_t rxchar_cb;
/**
* @brief Receive error callback.
*/
- uartecb_t uc_rxerr;
+ uartecb_t rxerr_cb;
/* End of the mandatory fields.*/
/**
* @brief Bit rate.
*/
- uint32_t uc_speed;
+ uint32_t speed;
/**
* @brief Initialization value for the CR1 register.
*/
- uint16_t uc_cr1;
+ uint16_t cr1;
/**
* @brief Initialization value for the CR2 register.
*/
- uint16_t uc_cr2;
+ uint16_t cr2;
/**
* @brief Initialization value for the CR3 register.
*/
- uint16_t uc_cr3;
+ uint16_t cr3;
} UARTConfig;
/**
@@ -255,19 +238,19 @@ struct UARTDriver {
/**
* @brief Driver state.
*/
- uartstate_t ud_state;
+ uartstate_t state;
/**
* @brief Transmitter state.
*/
- uarttxstate_t ud_txstate;
+ uarttxstate_t txstate;
/**
* @brief Receiver state.
*/
- uartrxstate_t ud_rxstate;
+ uartrxstate_t rxstate;
/**
* @brief Current configuration data.
*/
- const UARTConfig *ud_config;
+ const UARTConfig *config;
#if defined(UART_DRIVER_EXT_FIELDS)
UART_DRIVER_EXT_FIELDS
#endif
@@ -275,27 +258,27 @@ struct UARTDriver {
/**
* @brief Pointer to the USART registers block.
*/
- USART_TypeDef *ud_usart;
+ USART_TypeDef *usart;
/**
* @brief Pointer to the DMA registers block.
*/
- stm32_dma_t *ud_dmap;
+ stm32_dma_t *dmap;
/**
* @brief DMA priority bit mask.
*/
- uint32_t ud_dmaccr;
+ uint32_t dmaccr;
/**
* @brief Receive DMA channel.
*/
- uint8_t ud_dmarx;
+ uint8_t dmarx;
/**
* @brief Transmit DMA channel.
*/
- uint8_t ud_dmatx;
+ uint8_t dmatx;
/**
* @brief Default receive buffer while into @p UART_RX_IDLE state.
*/
- volatile uint16_t ud_rxbuf;
+ volatile uint16_t rxbuf;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/usb_lld.c b/os/hal/platforms/STM32/usb_lld.c
index 3fe6771ea..331eb38c3 100644
--- a/os/hal/platforms/STM32/usb_lld.c
+++ b/os/hal/platforms/STM32/usb_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -29,7 +30,6 @@
#include "ch.h"
#include "hal.h"
-#include "usb.h"
#if HAL_USE_USB || defined(__DOXYGEN__)
@@ -44,33 +44,123 @@
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 USBEndpointState ep0state;
+static union {
+ /**
+ * @brief IN EP0 state.
+ */
+ USBInEndpointState in;
+ /**
+ * @brief OUT EP0 state.
+ */
+ USBOutEndpointState out;
+} ep0_state;
/**
* @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,
- EPR_EP_TYPE_CONTROL | EPR_STAT_TX_STALL | EPR_STAT_RX_VALID,
- 0x40,
- 0x80
+ &ep0_state.in,
+ &ep0_state.out
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
+/**
+ * @brief Resets the packet memory allocator.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ */
+static void pm_reset(USBDriver *usbp) {
+
+ /* The first 64 bytes are reserved for the descriptors table. The effective
+ available RAM for endpoint buffers is just 448 bytes.*/
+ usbp->pmnext = 64;
+}
+
+/**
+ * @brief Resets the packet memory allocator.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] size size of the packet buffer to allocate
+ */
+static uint32_t pm_alloc(USBDriver *usbp, size_t size) {
+ uint32_t next;
+
+ next = usbp->pmnext;
+ usbp->pmnext += size;
+ chDbgAssert(usbp->pmnext > USB_PMA_SIZE, "pm_alloc(), #1", "PMA overflow");
+ return next;
+}
+
+/**
+ * @brief Copies a packet from memory into a packet buffer.
+ *
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the endpoint data
+ * @param[in] n maximum number of bytes to copy
+ */
+static void write_packet(usbep_t ep, const uint8_t *buf, size_t n){
+ uint32_t *pmap;
+ stm32_usb_descriptor_t *udp;
+ size_t count;
+
+ udp = USB_GET_DESCRIPTOR(ep);
+ pmap = USB_ADDR2PTR(udp->TXADDR);
+ udp->TXCOUNT = n;
+ count = (n + 1) / 2;
+ while (count) {
+ *pmap++ = *(uint16_t *)buf;
+ buf += 2;
+ count--;
+ }
+ EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
+}
+
+/**
+ * @brief Copies a packet from a packet buffer into memory.
+ *
+ * @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 packet size.
+ * @retval 0 Special case, zero sized packet.
+ */
+static size_t read_packet(usbep_t ep, uint8_t *buf, size_t n){
+ uint32_t *pmap;
+ stm32_usb_descriptor_t *udp;
+ size_t count;
+
+ udp = USB_GET_DESCRIPTOR(ep);
+ pmap = USB_ADDR2PTR(udp->RXADDR);
+ count = udp->RXCOUNT & RXCOUNT_COUNT_MASK;
+ if (n > count)
+ n = count;
+ count = (n + 1) / 2;
+ while (count) {
+ *(uint16_t *)buf = (uint16_t)*pmap++;
+ buf += 2;
+ count--;
+ }
+ return n;
+}
+
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
@@ -95,6 +185,7 @@ CH_IRQ_HANDLER(USB_HP_IRQHandler) {
*/
CH_IRQ_HANDLER(USB_LP_IRQHandler) {
uint32_t istr;
+ size_t n;
USBDriver *usbp = &USBD1;
CH_IRQ_PROLOGUE();
@@ -104,15 +195,40 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
/* USB bus reset condition handling.*/
if (istr & ISTR_RESET) {
_usb_reset(usbp);
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_RESET);
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_RESET);
STM32_USB->ISTR = ~ISTR_RESET;
}
+ /* USB bus SUSPEND condition handling.*/
+ if (istr & ISTR_SUSP) {
+ STM32_USB->CNTR |= CNTR_FSUSP;
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_SUSPEND);
+#if STM32_USB_LOW_POWER_ON_SUSPEND
+ STM32_USB->CNTR |= CNTR_LP_MODE;
+#endif
+ STM32_USB->ISTR = ~ISTR_SUSP;
+ }
+
+ /* USB bus WAKEUP condition handling.*/
+ if (istr & ISTR_WKUP) {
+ uint32_t fnr = STM32_USB->FNR;
+ if (!(fnr & FNR_RXDP)) {
+ STM32_USB->CNTR &= ~CNTR_FSUSP;
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_WAKEUP);
+ }
+#if STM32_USB_LOW_POWER_ON_SUSPEND
+ else {
+ /* Just noise, going back in SUSPEND mode, reference manual 22.4.5,
+ table 169.*/
+ STM32_USB->CNTR |= CNTR_LP_MODE;
+ }
+#endif
+ STM32_USB->ISTR = ~ISTR_WKUP;
+ }
+
/* SOF handling.*/
if (istr & ISTR_SOF) {
- if (usbp->usb_config->uc_sof_cb)
- usbp->usb_config->uc_sof_cb(usbp);
+ _usb_isr_invoke_sof_cb(usbp);
STM32_USB->ISTR = ~ISTR_SOF;
}
@@ -120,19 +236,63 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
while (istr & ISTR_CTR) {
uint32_t ep;
uint32_t epr = STM32_USB->EPR[ep = istr & ISTR_EP_ID_MASK];
- const USBEndpointConfig *epcp = usbp->usb_ep[ep]->uep_config;
+ const USBEndpointConfig *epcp = usbp->epc[ep];
if (epr & EPR_CTR_TX) {
/* IN endpoint, transmission.*/
EPR_CLEAR_CTR_TX(ep);
- if (epcp->uepc_in_cb)
- epcp->uepc_in_cb(usbp, ep);
+ if (epcp->ep_mode & USB_EP_MODE_PACKET) {
+ /* Packet mode, just invokes the callback.*/
+ _usb_isr_invoke_in_cb(usbp, ep);
+ }
+ else {
+ /* Transaction mode.*/
+ n = USB_GET_DESCRIPTOR(ep)->TXCOUNT;
+ epcp->in_state->txbuf += n;
+ epcp->in_state->txcnt += n;
+ epcp->in_state->txsize -= n;
+ if (epcp->in_state->txsize > 0) {
+ /* Transfer not completed, there are more packets to send.*/
+ if (epcp->in_state->txsize > epcp->in_maxsize)
+ n = epcp->in_maxsize;
+ else
+ n = epcp->in_state->txsize;
+ write_packet(ep, epcp->in_state->txbuf, n);
+ }
+ else {
+ /* Transfer completed, invokes the callback.*/
+ _usb_isr_invoke_in_cb(usbp, ep);
+ }
+ }
}
if (epr & EPR_CTR_RX) {
- /* OUT endpoint, receive.*/
EPR_CLEAR_CTR_RX(ep);
- if (epcp->uepc_out_cb)
- epcp->uepc_out_cb(usbp, ep);
+ /* OUT endpoint, receive.*/
+ if (epr & EPR_SETUP) {
+ /* Setup packets handling, setup packets are handled using a
+ specific callback.*/
+ _usb_isr_invoke_setup_cb(usbp, ep);
+ }
+ else if (epcp->ep_mode & USB_EP_MODE_PACKET) {
+ /* Packet mode, just invokes the callback.*/
+ _usb_isr_invoke_out_cb(usbp, ep);
+ }
+ else {
+ /* Transaction mode.*/
+ n = read_packet(ep, epcp->out_state->rxbuf, epcp->out_state->rxsize);
+ epcp->out_state->rxbuf += n;
+ epcp->out_state->rxcnt += n;
+ epcp->out_state->rxsize -= n;
+ epcp->out_state->rxpkts -= 1;
+ if (epcp->out_state->rxpkts > 0) {
+ /* Transfer not completed, there are more packets to receive.*/
+ EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
+ }
+ else {
+ /* Transfer completed, invokes the callback.*/
+ _usb_isr_invoke_out_cb(usbp, ep);
+ }
+ }
}
istr = STM32_USB->ISTR;
}
@@ -152,10 +312,6 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
*/
void usb_lld_init(void) {
- /* USB reset, ensures reset state in order to avoid trouble with JTAGs.*/
- RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
- RCC->APB1RSTR = 0;
-
/* Driver initialization.*/
usbObjectInit(&USBD1);
}
@@ -169,7 +325,7 @@ void usb_lld_init(void) {
*/
void usb_lld_start(USBDriver *usbp) {
- if (usbp->usb_state == USB_STOP) {
+ if (usbp->state == USB_STOP) {
/* Clock activation.*/
#if STM32_USB_USE_USB1
if (&USBD1 == usbp) {
@@ -183,11 +339,12 @@ void usb_lld_start(USBDriver *usbp) {
CORTEX_PRIORITY_MASK(STM32_USB_USB1_HP_IRQ_PRIORITY));
NVICEnableVector(USB_LP_CAN1_RX0_IRQn,
CORTEX_PRIORITY_MASK(STM32_USB_USB1_LP_IRQ_PRIORITY));
-
- /* Reset procedure enforced on driver start.*/
- _usb_reset(&USBD1);
+ /* Releases the USB reset.*/
+ STM32_USB->CNTR = 0;
}
#endif
+ /* Reset procedure enforced on driver start.*/
+ _usb_reset(usbp);
}
/* Configuration.*/
}
@@ -202,11 +359,12 @@ void usb_lld_start(USBDriver *usbp) {
void usb_lld_stop(USBDriver *usbp) {
/* If in ready state then disables the USB clock.*/
- if (usbp->usb_state == USB_STOP) {
+ if (usbp->state == USB_STOP) {
#if STM32_ADC_USE_ADC1
if (&USBD1 == usbp) {
NVICDisableVector(USB_HP_CAN1_TX_IRQn);
NVICDisableVector(USB_LP_CAN1_RX0_IRQn);
+ STM32_USB->CNTR = CNTR_PDWN | CNTR_FRES;
RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
}
#endif
@@ -223,25 +381,23 @@ void usb_lld_stop(USBDriver *usbp) {
void usb_lld_reset(USBDriver *usbp) {
uint32_t cntr;
- /* Powers up the transceiver while holding the USB in reset state.*/
- STM32_USB->CNTR = CNTR_FRES;
-
- /* Releases the USB reset, BTABLE is reset to zero.*/
- STM32_USB->CNTR = 0;
+ /* Post reset initialization.*/
+ STM32_USB->BTABLE = 0;
STM32_USB->ISTR = 0;
STM32_USB->DADDR = DADDR_EF;
- cntr = /*CNTR_ESOFM | */ CNTR_RESETM | /*CNTR_SUSPM |*/
- /*CNTR_WKUPM | CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM;
+ cntr = /*CNTR_ESOFM | */ CNTR_RESETM | CNTR_SUSPM |
+ CNTR_WKUPM | /*CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM;
/* The SOF interrupt is only enabled if a callback is defined for
this service because it is an high rate source.*/
- if (usbp->usb_config->uc_sof_cb != NULL)
+ if (usbp->config->sof_cb != NULL)
cntr |= CNTR_SOFM;
STM32_USB->CNTR = cntr;
+ /* Resets the packet memory allocator.*/
+ pm_reset(usbp);
+
/* EP0 initialization.*/
- memset(&ep0state, 0, sizeof ep0state);
- ep0state.uep_config = &ep0config;
- usbp->usb_ep[0] = &ep0state;
+ usbp->epc[0] = &ep0config;
usb_lld_init_endpoint(usbp, 0);
}
@@ -249,14 +405,12 @@ void usb_lld_reset(USBDriver *usbp) {
* @brief Sets the USB address.
*
* @param[in] usbp pointer to the @p USBDriver object
- * @param[in] addr the USB address
*
* @notapi
*/
-void usb_lld_set_address(USBDriver *usbp, uint8_t addr) {
+void usb_lld_set_address(USBDriver *usbp) {
- (void)usbp;
- STM32_USB->DADDR = (uint32_t)addr | DADDR_EF;
+ STM32_USB->DADDR = (uint32_t)(usbp->address) | DADDR_EF;
}
/**
@@ -268,25 +422,55 @@ void usb_lld_set_address(USBDriver *usbp, uint8_t addr) {
* @notapi
*/
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
- uint16_t nblocks;
+ uint16_t nblocks, epr;
stm32_usb_descriptor_t *dp;
- const USBEndpointConfig *epcp = usbp->usb_ep[ep]->uep_config;
+ const USBEndpointConfig *epcp = usbp->epc[ep];
+
+ /* Setting the endpoint type.*/
+ switch (epcp->ep_mode & USB_EP_MODE_TYPE) {
+ case USB_EP_MODE_TYPE_ISOC:
+ epr = EPR_EP_TYPE_ISO;
+ break;
+ case USB_EP_MODE_TYPE_BULK:
+ epr = EPR_EP_TYPE_BULK;
+ break;
+ case USB_EP_MODE_TYPE_INTR:
+ epr = EPR_EP_TYPE_INTERRUPT;
+ break;
+ default:
+ epr = EPR_EP_TYPE_CONTROL;
+ }
+
+ /* IN endpoint settings, always in NAK mode initially.*/
+ if (epcp->in_cb != NULL)
+ epr |= EPR_STAT_TX_NAK;
+
+ /* OUT endpoint settings. If the endpoint is in packet mode then it must
+ start ready to accept data else it must start in NAK mode.*/
+ if (epcp->out_cb != NULL) {
+ if (epcp->ep_mode & USB_EP_MODE_PACKET) {
+ usbp->receiving |= (1 << ep);
+ epr |= EPR_STAT_RX_VALID;
+ }
+ else
+ epr |= EPR_STAT_RX_NAK;
+ }
/* EPxR register setup.*/
- EPR_SET(ep, epcp->uepc_epr | ep);
- EPR_TOGGLE(ep, epcp->uepc_epr);
+ EPR_SET(ep, epr | ep);
+ EPR_TOGGLE(ep, epr);
/* Endpoint size and address initialization.*/
- if (epcp->uepc_out_maxsize > 62)
- nblocks = (((((epcp->uepc_out_maxsize - 1) | 0x1f) + 1) / 32) << 10) |
+ if (epcp->out_maxsize > 62)
+ nblocks = (((((epcp->out_maxsize - 1) | 0x1f) + 1) / 32) << 10) |
0x8000;
else
- nblocks = ((((epcp->uepc_out_maxsize - 1) | 1) + 1) / 2) << 10;
+ nblocks = ((((epcp->out_maxsize - 1) | 1) + 1) / 2) << 10;
dp = USB_GET_DESCRIPTOR(ep);
dp->TXCOUNT = 0;
dp->RXCOUNT = nblocks;
- dp->TXADDR = epcp->uepc_inaddr;
- dp->RXADDR = epcp->uepc_outaddr;
+ dp->TXADDR = pm_alloc(usbp, epcp->in_maxsize);
+ dp->RXADDR = pm_alloc(usbp, epcp->out_maxsize);
}
/**
@@ -299,232 +483,275 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
void usb_lld_disable_endpoints(USBDriver *usbp) {
unsigned i;
- (void)usbp;
+ /* Resets the packet memory allocator.*/
+ pm_reset(usbp);
+
+ /* Disabling all endpoints.*/
for (i = 1; i <= USB_ENDOPOINTS_NUMBER; i++) {
EPR_TOGGLE(i, 0);
EPR_SET(i, 0);
}
+}
+/**
+ * @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;
+ switch (STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) {
+ case EPR_STAT_RX_DIS:
+ return EP_STATUS_DISABLED;
+ case EPR_STAT_RX_STALL:
+ return EP_STATUS_STALLED;
+ default:
+ return EP_STATUS_ACTIVE;
+ }
}
/**
- * @brief Returns the number of bytes readable from the receive packet
- * buffer.
+ * @brief Returns the status of an IN endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @return The number of bytes that are effectively available.
- * @retval 0 Data not yet available.
+ * @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
*/
-size_t usb_lld_get_readable(USBDriver *usbp, usbep_t ep) {
+usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
(void)usbp;
- if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_NAK)
- return 0;
- return (size_t)(USB_GET_DESCRIPTOR(ep)->RXCOUNT & RXCOUNT_COUNT_MASK);
+ switch (STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) {
+ case EPR_STAT_TX_DIS:
+ return EP_STATUS_DISABLED;
+ case EPR_STAT_TX_STALL:
+ return EP_STATUS_STALLED;
+ default:
+ return EP_STATUS_ACTIVE;
+ }
}
/**
- * @brief Endpoint read.
- * @details The buffered packet is copied into the user buffer and then
- * the endpoint is brought to the valid state in order to allow
- * reception of more data.
+ * @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 endpoint data
- * @param[in] n maximum number of bytes to copy
- * @return The number of bytes that were effectively available.
- * @retval 0 Data not yet available.
+ * @param[out] buf buffer where to copy the packet data
*
* @notapi
*/
-size_t usb_lld_read(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) {
+void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
uint32_t *pmap;
stm32_usb_descriptor_t *udp;
- size_t count;
+ uint32_t n;
(void)usbp;
- if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_NAK)
- return 0;
-
udp = USB_GET_DESCRIPTOR(ep);
pmap = USB_ADDR2PTR(udp->RXADDR);
- count = udp->RXCOUNT & RXCOUNT_COUNT_MASK;
- if (n > count)
- n = count;
- count = (n + 1) / 2;
- while (count) {
+ for (n = 0; n < 4; n++) {
*(uint16_t *)buf = (uint16_t)*pmap++;
buf += 2;
- count--;
}
EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
- return n;
}
+
/**
- * @brief Returns the number of bytes writeable to the transmit packet
- * buffer.
+ * @brief Reads a packet from the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to accept another packet.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @return The number of bytes that can be written.
- * @retval 0 Endpoint not ready for transmission.
+ * @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.
*
- * @iclass
+ * @notapi
*/
-size_t usb_lld_get_writeable(USBDriver *usbp, usbep_t ep) {
+size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+ uint32_t *pmap;
+ stm32_usb_descriptor_t *udp;
+ size_t count;
- if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_NAK)
- return 0;
- return (size_t)usbp->usb_ep[ep]->uep_config->uepc_in_maxsize;
+ (void)usbp;
+ udp = USB_GET_DESCRIPTOR(ep);
+ pmap = USB_ADDR2PTR(udp->RXADDR);
+ count = udp->RXCOUNT & RXCOUNT_COUNT_MASK;
+ if (n > count)
+ n = count;
+ n = (n + 1) / 2;
+ while (n > 0) {
+ *(uint16_t *)buf = (uint16_t)*pmap++;
+ buf += 2;
+ n--;
+ }
+ EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
+ return count;
}
/**
- * @brief Endpoint write.
- * @details The user data is copied in the packer memory and then
- * the endpoint is brought to the valid state in order to allow
- * transmission.
+ * @brief Writes a packet to the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to transmit the packet.
*
* @param[in] usbp pointer to the @p USBDriver object
* @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.
- * @retval 0 Endpoint not ready for transmission.
+ * @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
*/
-size_t usb_lld_write(USBDriver *usbp, usbep_t ep,
- const uint8_t *buf,
- size_t n) {
+void usb_lld_write_packet(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
uint32_t *pmap;
stm32_usb_descriptor_t *udp;
- size_t count;
(void)usbp;
- if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_NAK)
- return 0;
-
udp = USB_GET_DESCRIPTOR(ep);
pmap = USB_ADDR2PTR(udp->TXADDR);
udp->TXCOUNT = n;
- count = (n + 1) / 2;
- while (count) {
+ n = (n + 1) / 2;
+ while (n > 0) {
*pmap++ = *(uint16_t *)buf;
buf += 2;
- count--;
+ n--;
}
EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
- return n;
}
/**
- * @brief Returns the status of an IN endpoint.
+ * @brief Starts a receive operation on an OUT endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the endpoint data
+ * @param[in] n maximum number of bytes to copy in the buffer
*
* @notapi
*/
-usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
-
- (void)usbp;
- switch (STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) {
- case EPR_STAT_TX_DIS:
- return EP_STATUS_DISABLED;
- case EPR_STAT_TX_STALL:
- return EP_STATUS_STALLED;
- default:
- return EP_STATUS_ACTIVE;
- }
+void usb_lld_start_out(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+ USBOutEndpointState *osp = usbp->epc[ep]->out_state;
+
+ osp->rxbuf = buf;
+ osp->rxsize = n;
+ osp->rxcnt = 0;
+ if (osp->rxsize == 0) /* Special case for zero sized packets.*/
+ osp->rxpkts = 1;
+ else
+ osp->rxpkts = (uint16_t)((n + usbp->epc[ep]->out_maxsize - 1) /
+ usbp->epc[ep]->out_maxsize);
+ EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
}
/**
- * @brief Returns the status of an OUT endpoint.
+ * @brief Starts a transmit operation on an IN endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the endpoint data
+ * @param[in] n maximum number of bytes to copy
*
* @notapi
*/
-usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
-
- (void)usbp;
- switch (STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) {
- case EPR_STAT_RX_DIS:
- return EP_STATUS_DISABLED;
- case EPR_STAT_RX_STALL:
- return EP_STATUS_STALLED;
- default:
- return EP_STATUS_ACTIVE;
- }
+void usb_lld_start_in(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 > (size_t)usbp->epc[ep]->in_maxsize)
+ n = (size_t)usbp->epc[ep]->in_maxsize;
+ write_packet(ep, buf, n);
}
/**
- * @brief Brings an IN endpoint in the stalled state.
+ * @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_in(USBDriver *usbp, usbep_t ep) {
+void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
(void)usbp;
- EPR_SET_STAT_TX(ep, EPR_STAT_TX_STALL);
+ EPR_SET_STAT_RX(ep, EPR_STAT_RX_STALL);
}
/**
- * @brief Brings an OUT endpoint in the stalled state.
+ * @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_out(USBDriver *usbp, usbep_t ep) {
+void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
(void)usbp;
- EPR_SET_STAT_RX(ep, EPR_STAT_RX_STALL);
+ EPR_SET_STAT_TX(ep, EPR_STAT_TX_STALL);
}
/**
- * @brief Brings an IN endpoint in the active state.
+ * @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_in(USBDriver *usbp, usbep_t ep) {
+void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
(void)usbp;
/* Makes sure to not put to NAK an endpoint that is already
transferring.*/
- if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_VALID)
- EPR_SET_STAT_TX(ep, EPR_STAT_TX_NAK);
+ if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_VALID)
+ EPR_SET_STAT_TX(ep, EPR_STAT_RX_NAK);
}
/**
- * @brief Brings an OUT endpoint in the active state.
+ * @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_out(USBDriver *usbp, usbep_t ep) {
+void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
(void)usbp;
/* Makes sure to not put to NAK an endpoint that is already
transferring.*/
- if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_VALID)
- EPR_SET_STAT_TX(ep, EPR_STAT_RX_NAK);
+ if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_VALID)
+ EPR_SET_STAT_TX(ep, EPR_STAT_TX_NAK);
}
#endif /* HAL_USE_USB */
diff --git a/os/hal/platforms/STM32/usb_lld.h b/os/hal/platforms/STM32/usb_lld.h
index e21bbecd2..9b5e9dad2 100644
--- a/os/hal/platforms/STM32/usb_lld.h
+++ b/os/hal/platforms/STM32/usb_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -41,6 +42,11 @@
*/
#define USB_MAX_ENDPOINTS USB_ENDOPOINTS_NUMBER
+/**
+ * @brief This device requires the address change after the status packet.
+ */
+#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -55,6 +61,13 @@
#endif
/**
+ * @brief Enables the USB device low power mode on suspend.
+ */
+#if !defined(STM32_USB_LOW_POWER_ON_SUSPEND) || defined(__DOXYGEN__)
+#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
+#endif
+
+/**
* @brief USB1 interrupt priority level setting.
*/
#if !defined(STM32_USB_USB1_HP_IRQ_PRIORITY) || defined(__DOXYGEN__)
@@ -89,84 +102,105 @@
/*===========================================================================*/
/**
- * @brief Type of an USB Endpoint configuration structure.
- * @note Platform specific restrictions may apply to endpoints.
+ * @brief Type of an endpoint state structure.
*/
typedef struct {
/**
- * @brief IN endpoint notification callback.
+ * @brief Pointer to the transmission buffer.
*/
- usbepcallback_t uepc_in_cb;
+ const uint8_t *txbuf;
/**
- * @brief OUT endpoint notification callback.
+ * @brief Requested transmit transfer size.
*/
- usbepcallback_t uepc_out_cb;
+ size_t txsize;
/**
- * @brief IN endpoint maximum packet size.
+ * @brief Transmitted bytes so far.
*/
- uint16_t uepc_in_maxsize;
+ size_t txcnt;
+} USBInEndpointState;
+
+/**
+ * @brief Type of an endpoint state structure.
+ */
+typedef struct {
/**
- * @brief OUT endpoint maximum packet size.
+ * @brief Number of packets to receive.
*/
- uint16_t uepc_out_maxsize;
- /* End of the mandatory fields.*/
+ uint16_t rxpkts;
/**
- * @brief EPxR register initialization value.
- * @note Do not specify the EA field, leave it to zero.
+ * @brief Pointer to the receive buffer.
*/
- uint16_t uepc_epr;
+ uint8_t *rxbuf;
/**
- * @brief Endpoint IN buffer address as offset in the PMA.
+ * @brief Requested receive transfer size.
*/
- uint16_t uepc_inaddr;
+ size_t rxsize;
/**
- * @brief Endpoint OUT buffer address as offset in the PMA.
+ * @brief Received bytes so far.
*/
- uint16_t uepc_outaddr;
-} USBEndpointConfig;
-
+ size_t rxcnt;
+} USBOutEndpointState;
/**
- * @brief Type of an endpoint state structure.
+ * @brief Type of an USB endpoint configuration structure.
+ * @note Platform specific restrictions may apply to endpoints.
*/
typedef struct {
/**
- * @brief Configuration associated to the endpoint.
+ * @brief Type and mode of the endpoint.
*/
- const USBEndpointConfig *uep_config;
+ uint32_t ep_mode;
/**
- * @brief Pointer to the transmission buffer.
+ * @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.
*/
- const uint8_t *uep_txbuf;
+ usbepcallback_t setup_cb;
/**
- * @brief Pointer to the receive buffer.
+ * @brief IN endpoint notification callback.
+ * @details This field must be set to @p NULL if the IN endpoint is not
+ * used.
*/
- uint8_t *uep_rxbuf;
+ usbepcallback_t in_cb;
/**
- * @brief Requested transmit transfer size.
+ * @brief OUT endpoint notification callback.
+ * @details This field must be set to @p NULL if the OUT endpoint is not
+ * used.
*/
- size_t uep_txsize;
- /**
- * @brief Requested receive transfer size.
- */
- size_t uep_rxsize;
+ usbepcallback_t out_cb;
/**
- * @brief Transmitted bytes so far.
+ * @brief IN endpoint maximum packet size.
+ * @details This field must be set to zero if the IN endpoint is not
+ * used.
*/
- size_t uep_txcnt;
+ uint16_t in_maxsize;
/**
- * @brief Received bytes so far.
- */
- size_t uep_rxcnt;
+ * @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 TRUE if transmitting else @p FALSE.
+ * @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.
*/
- uint8_t uep_transmitting;
+ USBInEndpointState *in_state;
/**
- * @brief @p TRUE if receiving else @p FALSE.
+ * @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.
*/
- uint8_t uep_receiving;
-} USBEndpointState;
+ USBOutEndpointState *out_state;
+ /* End of the mandatory fields.*/
+} USBEndpointConfig;
/**
* @brief Type of an USB driver configuration structure.
@@ -176,22 +210,22 @@ typedef struct {
* @brief USB events callback.
* @details This callback is invoked when an USB driver event is registered.
*/
- usbeventcb_t uc_event_cb;
+ usbeventcb_t event_cb;
/**
* @brief Device GET_DESCRIPTOR request callback.
* @note This callback is mandatory and cannot be set to @p NULL.
*/
- usbgetdescriptor_t uc_get_descriptor_cb;
+ 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 uc_requests_hook_cb;
+ usbreqhandler_t requests_hook_cb;
/**
* @brief Start Of Frame callback.
*/
- usbcallback_t uc_sof_cb;
+ usbcallback_t sof_cb;
/* End of the mandatory fields.*/
} USBConfig;
@@ -202,61 +236,68 @@ struct USBDriver {
/**
* @brief Driver state.
*/
- usbstate_t usb_state;
+ usbstate_t state;
/**
* @brief Current configuration data.
*/
- const USBConfig *usb_config;
+ const USBConfig *config;
/**
* @brief Field available to user, it can be used to associate an
* application-defined handler to the USB driver.
*/
- void *usb_param;
+ void *param;
/**
- * @brief Active endpoints configurations.
+ * @brief Bit map of the transmitting IN endpoints.
*/
- USBEndpointState *usb_ep[USB_MAX_ENDPOINTS + 1];
+ uint16_t transmitting;
/**
- * @brief Endpoint 0 state.
+ * @brief Bit map of the receiving OUT endpoints.
*/
- usbep0state_t usb_ep0state;
+ uint16_t receiving;
/**
- * @brief Next position in the buffer to be transferred through endpoint 0.
+ * @brief Active endpoints configurations.
*/
- uint8_t *usb_ep0next;
+ const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1];
/**
- * @brief Maximum number of bytes to be tranferred through endpoint 0.
+ * @brief Endpoint 0 state.
*/
- size_t usb_ep0max;
+ usbep0state_t ep0state;
/**
- * @brief Number of bytes yet to be tranferred through endpoint 0.
+ * @brief Next position in the buffer to be transferred through endpoint 0.
*/
- size_t usb_ep0n;
+ uint8_t *ep0next;
/**
- * @brief Size of the last packet transferred through endpoint 0.
+ * @brief Number of bytes yet to be transferred through endpoint 0.
*/
- size_t usb_ep0lastsize;
+ size_t ep0n;
/**
* @brief Endpoint 0 end transaction callback.
*/
- usbcallback_t usb_ep0endcb;
+ usbcallback_t ep0endcb;
/**
* @brief Setup packet buffer.
*/
- uint8_t usb_setup[8];
+ uint8_t setup[8];
/**
* @brief Current USB device status.
*/
- uint16_t usb_status;
+ uint16_t status;
/**
* @brief Assigned USB address.
*/
- uint8_t usb_address;
+ uint8_t address;
/**
* @brief Current USB device configuration.
*/
- uint8_t usb_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;
};
/*===========================================================================*/
@@ -270,7 +311,7 @@ struct USBDriver {
*
* @notapi
*/
-#define usb_lld_fetch_word(p) (*(uint16_t *)p)
+#define usb_lld_fetch_word(p) (*(uint16_t *)(p))
/**
* @brief Returns the current frame number.
@@ -282,6 +323,37 @@ struct USBDriver {
*/
#define usb_lld_get_frame_number(usbp) (STM32_USB->FNR & FNR_FN_MASK)
+/**
+ * @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 Returns the exact size of a received packet.
+ * @pre The OUT endpoint must have been configured in packet 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_packet_size(usbp, ep) \
+ ((size_t)USB_GET_DESCRIPTOR(ep)->RXCOUNT & RXCOUNT_COUNT_MASK)
+
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@@ -290,14 +362,6 @@ struct USBDriver {
extern USBDriver USBD1;
#endif
-#if !defined(__DOXYGEN__)
-extern const USBEndpointConfig usb_lld_ep0config;
-#endif
-
-#if !defined(__DOXYGEN__)
-extern USBEndpointState usb_lld_ep0state;
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -305,20 +369,24 @@ extern "C" {
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, uint8_t addr);
+ void usb_lld_set_address(USBDriver *usbp);
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep);
void usb_lld_disable_endpoints(USBDriver *usbp);
- size_t usb_lld_get_readable(USBDriver *usbp, usbep_t ep);
- size_t usb_lld_read(USBDriver *usbp, usbep_t ep,
- uint8_t *buf, size_t n);
- size_t usb_lld_write(USBDriver *usbp, usbep_t ep,
- const uint8_t *buf, size_t n);
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(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ void usb_lld_write_packet(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
+ void usb_lld_start_out(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ void usb_lld_start_in(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
void usb_lld_stall_out(USBDriver *usbp, usbep_t ep);
- void usb_lld_clear_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
diff --git a/os/hal/platforms/STM8L/hal_lld.c b/os/hal/platforms/STM8L/hal_lld.c
index 72cb830f3..e2f3c6a7b 100644
--- a/os/hal/platforms/STM8L/hal_lld.c
+++ b/os/hal/platforms/STM8L/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/hal_lld.h b/os/hal/platforms/STM8L/hal_lld.h
index 2e21988e7..159bd0c71 100644
--- a/os/hal/platforms/STM8L/hal_lld.h
+++ b/os/hal/platforms/STM8L/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/hal_lld_stm8l_hd.h b/os/hal/platforms/STM8L/hal_lld_stm8l_hd.h
index 9acad669b..efd3f187e 100644
--- a/os/hal/platforms/STM8L/hal_lld_stm8l_hd.h
+++ b/os/hal/platforms/STM8L/hal_lld_stm8l_hd.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/hal_lld_stm8l_md.h b/os/hal/platforms/STM8L/hal_lld_stm8l_md.h
index f1b1e89b8..e91035e36 100644
--- a/os/hal/platforms/STM8L/hal_lld_stm8l_md.h
+++ b/os/hal/platforms/STM8L/hal_lld_stm8l_md.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/hal_lld_stm8l_mdp.h b/os/hal/platforms/STM8L/hal_lld_stm8l_mdp.h
index f01c18af9..e08d62d8d 100644
--- a/os/hal/platforms/STM8L/hal_lld_stm8l_mdp.h
+++ b/os/hal/platforms/STM8L/hal_lld_stm8l_mdp.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/pal_lld.c b/os/hal/platforms/STM8L/pal_lld.c
index a91f380a4..e4c3001c6 100644
--- a/os/hal/platforms/STM8L/pal_lld.c
+++ b/os/hal/platforms/STM8L/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/pal_lld.h b/os/hal/platforms/STM8L/pal_lld.h
index 347fed85a..f42973218 100644
--- a/os/hal/platforms/STM8L/pal_lld.h
+++ b/os/hal/platforms/STM8L/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -174,7 +175,7 @@ typedef GPIO_TypeDef *ioportid_t;
*
* @notapi
*/
-#define pal_lld_init(config) *IOPORTS = *(config)
+#define pal_lld_init(config) (*IOPORTS = *(config))
/**
* @brief Reads the physical I/O port states.
@@ -214,7 +215,6 @@ typedef GPIO_TypeDef *ioportid_t;
*/
#define pal_lld_writeport(port, bits) ((port)->ODR = (bits))
-
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
@@ -230,7 +230,7 @@ typedef GPIO_TypeDef *ioportid_t;
* @notapi
*/
#define pal_lld_setgroupmode(port, mask, mode) \
- _pal_lld_setgroupmode(port, mask, mode)
+ _pal_lld_setgroupmode(port, mask, mode)
extern ROMCONST PALConfig pal_default_config;
diff --git a/os/hal/platforms/STM8L/platform.dox b/os/hal/platforms/STM8L/platform.dox
index b1b74251e..0a5f1b614 100644
--- a/os/hal/platforms/STM8L/platform.dox
+++ b/os/hal/platforms/STM8L/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -41,7 +42,7 @@
*/
/**
- * @defgroup STM8L_PAL STM8L GPIO Support
+ * @defgroup STM8L_PAL STM8L PAL Support
* @details The STM8L PAL driver uses the GPIO peripherals.
*
* @section stm8l_pal_1 Supported HW resources
@@ -84,7 +85,7 @@
*/
/**
- * @defgroup STM8L_SERIAL STM8L USART Support (buffered)
+ * @defgroup STM8L_SERIAL STM8L Serial Support
* @details The STM8L Serial driver uses the USART1 peripheral in a
* buffered, interrupt driven, implementation.
*
diff --git a/os/hal/platforms/STM8L/serial_lld.c b/os/hal/platforms/STM8L/serial_lld.c
index 887dd4967..372a48bf4 100644
--- a/os/hal/platforms/STM8L/serial_lld.c
+++ b/os/hal/platforms/STM8L/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8L/serial_lld.h b/os/hal/platforms/STM8L/serial_lld.h
index c4943433a..ca0de3b6d 100644
--- a/os/hal/platforms/STM8L/serial_lld.h
+++ b/os/hal/platforms/STM8L/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -144,7 +145,7 @@ typedef struct {
#if STM8L_SERIAL_USE_USART1 || defined(__DOXYGEN__)
/**
- * @brief USART1 RX interrupt handler segment.
+ * @brief USART1 RX interrupt handler segment.
*/
#define _USART1_RECEIVE_ISR() { \
uint8_t sr = USART1->SR; \
@@ -159,7 +160,7 @@ typedef struct {
}
/**
- * @brief USART1 TX interrupt handler segment.
+ * @brief USART1 TX interrupt handler segment.
*/
#define _USART1_TRANSMIT_ISR() { \
if (USART1->SR & USART_SR_TXE) { \
@@ -177,7 +178,7 @@ typedef struct {
#if STM8L_SERIAL_USE_USART2 || defined(__DOXYGEN__)
/**
- * @brief USART2 RX interrupt handler segment.
+ * @brief USART2 RX interrupt handler segment.
*/
#define _USART2_RECEIVE_ISR() { \
uint8_t sr = USART2->SR; \
@@ -192,7 +193,7 @@ typedef struct {
}
/**
- * @brief USART2 TX interrupt handler segment.
+ * @brief USART2 TX interrupt handler segment.
*/
#define _USART2_TRANSMIT_ISR() { \
if (USART2->SR & USART_SR_TXE) { \
@@ -210,7 +211,7 @@ typedef struct {
#if STM8L_SERIAL_USE_USART3 || defined(__DOXYGEN__)
/**
- * @brief USART3 RX interrupt handler segment.
+ * @brief USART3 RX interrupt handler segment.
*/
#define _USART3_RECEIVE_ISR() { \
uint8_t sr = USART3->SR; \
@@ -225,7 +226,7 @@ typedef struct {
}
/**
- * @brief USART3 TX interrupt handler segment.
+ * @brief USART3 TX interrupt handler segment.
*/
#define _USART3_TRANSMIT_ISR() { \
if (USART3->SR & USART_SR_TXE) { \
diff --git a/os/hal/platforms/STM8L/shared_isr.c b/os/hal/platforms/STM8L/shared_isr.c
index e89e1f78c..2bbb1a70b 100644
--- a/os/hal/platforms/STM8L/shared_isr.c
+++ b/os/hal/platforms/STM8L/shared_isr.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8S/hal_lld.c b/os/hal/platforms/STM8S/hal_lld.c
index de32cfb44..75772a3af 100644
--- a/os/hal/platforms/STM8S/hal_lld.c
+++ b/os/hal/platforms/STM8S/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8S/hal_lld.h b/os/hal/platforms/STM8S/hal_lld.h
index 1db8a742c..a57da439a 100644
--- a/os/hal/platforms/STM8S/hal_lld.h
+++ b/os/hal/platforms/STM8S/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -202,7 +203,7 @@
/**
* @brief CPU clock.
* @details On the STM8SS the CPU clock can be programmed to be a fraction of
- * the system clock.
+ * the system clock.
*/
#define CPUCLK (SYSCLK / (1 << STM8S_CPU_DIVIDER))
diff --git a/os/hal/platforms/STM8S/pal_lld.c b/os/hal/platforms/STM8S/pal_lld.c
index feb9c33cf..0a9b26657 100644
--- a/os/hal/platforms/STM8S/pal_lld.c
+++ b/os/hal/platforms/STM8S/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8S/pal_lld.h b/os/hal/platforms/STM8S/pal_lld.h
index 65f4584de..ef69d1379 100644
--- a/os/hal/platforms/STM8S/pal_lld.h
+++ b/os/hal/platforms/STM8S/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -159,7 +160,7 @@ typedef GPIO_TypeDef *ioportid_t;
*
* @notapi
*/
-#define pal_lld_init(config) *IOPORTS = *(config)
+#define pal_lld_init(config) (*IOPORTS = *(config))
/**
* @brief Reads the physical I/O port states.
@@ -199,7 +200,6 @@ typedef GPIO_TypeDef *ioportid_t;
*/
#define pal_lld_writeport(port, bits) ((port)->ODR = (bits))
-
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
@@ -215,7 +215,7 @@ typedef GPIO_TypeDef *ioportid_t;
* @notapi
*/
#define pal_lld_setgroupmode(port, mask, mode) \
- _pal_lld_setgroupmode(port, mask, mode)
+ _pal_lld_setgroupmode(port, mask, mode)
extern ROMCONST PALConfig pal_default_config;
diff --git a/os/hal/platforms/STM8S/platform.dox b/os/hal/platforms/STM8S/platform.dox
index d05bb4af6..8ff654170 100644
--- a/os/hal/platforms/STM8S/platform.dox
+++ b/os/hal/platforms/STM8S/platform.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -40,7 +41,7 @@
*/
/**
- * @defgroup STM8S_PAL STM8S GPIO Support
+ * @defgroup STM8S_PAL STM8S PAL Support
* @details The STM8S PAL driver uses the GPIO peripherals.
*
* @section stm8s_pal_1 Supported HW resources
@@ -83,26 +84,7 @@
*/
/**
- * @defgroup STM8S_SPI STM8S SPI Support
- * @details The SPI driver supports the STM8S SPI peripheral in an interrupt
- * driven implementation.
- * @note Being the SPI a fast peripheral, much care must be taken to
- * not saturate the CPU bandwidth with an excessive IRQ rate. The
- * maximum transfer bit rate is likely limited by the IRQ
- * handling.
- *
- * @section stm8s_spi_1 Supported HW resources
- * - SPI.
- * .
- * @section stm8s_spi_2 STM8S SPI driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Fully interrupt driven.
- * .
- * @ingroup STM8S
- */
-
-/**
- * @defgroup STM8S_SERIAL STM8S UART Support (buffered)
+ * @defgroup STM8S_SERIAL STM8S Serial Support
* @details The STM8S Serial driver uses the UART peripherals in a
* buffered, interrupt driven, implementation.
*
@@ -120,3 +102,22 @@
* .
* @ingroup STM8S
*/
+
+/**
+ * @defgroup STM8S_SPI STM8S SPI Support
+ * @details The SPI driver supports the STM8S SPI peripheral in an interrupt
+ * driven implementation.
+ * @note Being the SPI a fast peripheral, much care must be taken to
+ * not saturate the CPU bandwidth with an excessive IRQ rate. The
+ * maximum transfer bit rate is likely limited by the IRQ
+ * handling.
+ *
+ * @section stm8s_spi_1 Supported HW resources
+ * - SPI.
+ * .
+ * @section stm8s_spi_2 STM8S SPI driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Fully interrupt driven.
+ * .
+ * @ingroup STM8S
+ */
diff --git a/os/hal/platforms/STM8S/serial_lld.c b/os/hal/platforms/STM8S/serial_lld.c
index d5bdb96f0..50a389ab4 100644
--- a/os/hal/platforms/STM8S/serial_lld.c
+++ b/os/hal/platforms/STM8S/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -266,7 +267,7 @@ CH_IRQ_HANDLER(18) {
/**
* @brief IRQ 20 service routine.
*
- * @isr
+ * @isr
*/
CH_IRQ_HANDLER(20) {
msg_t b;
diff --git a/os/hal/platforms/STM8S/serial_lld.h b/os/hal/platforms/STM8S/serial_lld.h
index 96ac08896..fa8777bd5 100644
--- a/os/hal/platforms/STM8S/serial_lld.h
+++ b/os/hal/platforms/STM8S/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/STM8S/spi_lld.c b/os/hal/platforms/STM8S/spi_lld.c
index c950f0bd4..57e459d80 100644
--- a/os/hal/platforms/STM8S/spi_lld.c
+++ b/os/hal/platforms/STM8S/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -70,12 +71,12 @@ CH_IRQ_HANDLER(10) {
handle the case where a frame arrives immediately after reading the
DR register.*/
while ((SPI->SR & SPI_SR_RXNE) != 0) {
- if (SPID1.spd_rxptr != NULL)
- *SPID1.spd_rxptr++ = SPI->DR;
+ if (SPID1.rxptr != NULL)
+ *SPID1.rxptr++ = SPI->DR;
else
(void)SPI->DR;
- if (--SPID1.spd_rxcnt == 0) {
- chDbgAssert(SPID1.spd_txcnt == 0,
+ if (--SPID1.rxcnt == 0) {
+ chDbgAssert(SPID1.txcnt == 0,
"IRQ10, #1", "counter out of synch");
/* Stops all the IRQ sources.*/
SPI->ICR = 0;
@@ -89,8 +90,8 @@ CH_IRQ_HANDLER(10) {
}
/* Loading the DR register.*/
if ((SPI->SR & SPI_SR_TXE) != 0) {
- if (SPID1.spd_txptr != NULL)
- SPI->DR = *SPID1.spd_txptr++;
+ if (SPID1.txptr != NULL)
+ SPI->DR = *SPID1.txptr++;
else
SPI->DR = 0xFF;
}
@@ -129,8 +130,10 @@ void spi_lld_start(SPIDriver *spip) {
CLK->PCKENR1 |= CLK_PCKENR1_SPI; /* PCKEN11, clock source. */
/* Configuration.*/
- SPI->CR2 = 0;
- SPI->CR1 = spip->spd_config->spc_cr1 | SPI_CR1_MSTR | SPI_CR1_SPE;
+ SPI->CR1 = 0;
+ SPI->CR1 = spip->config->cr1 | SPI_CR1_MSTR;
+ SPI->CR2 = SPI_CR2_SSI | SPI_CR2_SSM;
+ SPI->CR1 |= SPI_CR1_SPE;
}
/**
@@ -162,7 +165,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
- palClearPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -175,7 +178,7 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
- palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
+ palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
@@ -191,9 +194,9 @@ void spi_lld_unselect(SPIDriver *spip) {
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
SPI->ICR = SPI_ICR_TXEI | SPI_ICR_RXEI | SPI_ICR_ERRIE;
}
@@ -215,9 +218,9 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
SPI->ICR = SPI_ICR_TXEI | SPI_ICR_RXEI | SPI_ICR_ERRIE;
}
@@ -236,9 +239,9 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
- spip->spd_rxptr = NULL;
- spip->spd_txptr = txbuf;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = NULL;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
SPI->ICR = SPI_ICR_TXEI | SPI_ICR_RXEI | SPI_ICR_ERRIE;
}
@@ -257,9 +260,9 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
- spip->spd_rxptr = rxbuf;
- spip->spd_txptr = NULL;
- spip->spd_rxcnt = spip->spd_txcnt = n;
+ spip->rxptr = rxbuf;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
SPI->ICR = SPI_ICR_TXEI | SPI_ICR_RXEI | SPI_ICR_ERRIE;
}
diff --git a/os/hal/platforms/STM8S/spi_lld.h b/os/hal/platforms/STM8S/spi_lld.h
index 1f665d01a..48af021b0 100644
--- a/os/hal/platforms/STM8S/spi_lld.h
+++ b/os/hal/platforms/STM8S/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -87,20 +88,20 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
- ioportid_t spc_ssport;
+ ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
- uint16_t spc_sspad;
+ uint16_t sspad;
/**
* @brief SPI initialization data.
*/
- uint8_t spc_cr1;
+ uint8_t cr1;
} SPIConfig;
/**
@@ -110,25 +111,25 @@ struct SPIDriver {
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
@@ -136,21 +137,21 @@ struct SPIDriver {
#endif
/* End of the mandatory fields.*/
/**
- * @brief Number of bytes yet to be received.
+ * @brief Number of bytes yet to be received.
*/
- uint16_t spd_rxcnt;
+ uint16_t rxcnt;
/**
* @brief Receive pointer or @p NULL.
*/
- uint8_t *spd_rxptr;
+ uint8_t *rxptr;
/**
* @brief Number of bytes yet to be transmitted.
*/
- uint16_t spd_txcnt;
+ uint16_t txcnt;
/**
* @brief Transmit pointer or @p NULL.
*/
- const uint8_t *spd_txptr;
+ const uint8_t *txptr;
};
/*===========================================================================*/
diff --git a/os/hal/platforms/Win32/console.c b/os/hal/platforms/Win32/console.c
index 737cf92bf..4f29b7900 100644
--- a/os/hal/platforms/Win32/console.c
+++ b/os/hal/platforms/Win32/console.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Win32/console.h b/os/hal/platforms/Win32/console.h
index 3a30e6295..b803a5de7 100644
--- a/os/hal/platforms/Win32/console.h
+++ b/os/hal/platforms/Win32/console.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Win32/hal_lld.c b/os/hal/platforms/Win32/hal_lld.c
index a03d91998..24a11f51c 100644
--- a/os/hal/platforms/Win32/hal_lld.c
+++ b/os/hal/platforms/Win32/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Win32/hal_lld.h b/os/hal/platforms/Win32/hal_lld.h
index 84696107b..fbeeaa61e 100644
--- a/os/hal/platforms/Win32/hal_lld.h
+++ b/os/hal/platforms/Win32/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Win32/pal_lld.c b/os/hal/platforms/Win32/pal_lld.c
index 54ff76100..b2a83d77f 100644
--- a/os/hal/platforms/Win32/pal_lld.c
+++ b/os/hal/platforms/Win32/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Win32/pal_lld.h b/os/hal/platforms/Win32/pal_lld.h
index b353f2a52..a1c84b13a 100644
--- a/os/hal/platforms/Win32/pal_lld.h
+++ b/os/hal/platforms/Win32/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -128,10 +129,9 @@ typedef sim_vio_port_t *ioportid_t;
*
* @param[in] config architecture-dependent ports configuration
*/
-#define pal_lld_init(config) { \
- vio_port_1 = (config)->VP1Data; \
- vio_port_2 = (config)->VP2Data; \
-}
+#define pal_lld_init(config) \
+ (vio_port_1 = (config)->VP1Data, \
+ vio_port_2 = (config)->VP2Data)
/**
* @brief Reads the physical I/O port states.
@@ -177,7 +177,7 @@ typedef sim_vio_port_t *ioportid_t;
* @param[in] mask group mask
* @param[in] mode group mode
*/
-#define pal_lld_setgroupmode(port, mask, mode) \
+#define pal_lld_setgroupmode(port, mask, mode) \
_pal_lld_setgroupmode(port, mask, mode)
#if !defined(__DOXYGEN__)
diff --git a/os/hal/platforms/Win32/serial_lld.c b/os/hal/platforms/Win32/serial_lld.c
index bbfae160f..6b76ebbc7 100644
--- a/os/hal/platforms/Win32/serial_lld.c
+++ b/os/hal/platforms/Win32/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/Win32/serial_lld.h b/os/hal/platforms/Win32/serial_lld.h
index fd6bff34d..a853a507d 100644
--- a/os/hal/platforms/Win32/serial_lld.h
+++ b/os/hal/platforms/Win32/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/platforms/platforms.dox b/os/hal/platforms/platforms.dox
index aa25cbca4..fba310bed 100644
--- a/os/hal/platforms/platforms.dox
+++ b/os/hal/platforms/platforms.dox
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/src/adc.c b/os/hal/src/adc.c
index 25cbfe750..4843ca90b 100644
--- a/os/hal/src/adc.c
+++ b/os/hal/src/adc.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,19 +68,19 @@ void adcInit(void) {
*/
void adcObjectInit(ADCDriver *adcp) {
- adcp->ad_state = ADC_STOP;
- adcp->ad_config = NULL;
- adcp->ad_samples = NULL;
- adcp->ad_depth = 0;
- adcp->ad_grpp = NULL;
+ adcp->state = ADC_STOP;
+ adcp->config = NULL;
+ adcp->samples = NULL;
+ adcp->depth = 0;
+ adcp->grpp = NULL;
#if ADC_USE_WAIT
- adcp->ad_thread = NULL;
+ adcp->thread = NULL;
#endif /* ADC_USE_WAIT */
#if ADC_USE_MUTUAL_EXCLUSION
#if CH_USE_MUTEXES
- chMtxInit(&adcp->ad_mutex);
+ chMtxInit(&adcp->mutex);
#else
- chSemInit(&adcp->ad_semaphore, 1);
+ chSemInit(&adcp->semaphore, 1);
#endif
#endif /* ADC_USE_MUTUAL_EXCLUSION */
#if defined(ADC_DRIVER_EXT_INIT_HOOK)
@@ -101,11 +102,11 @@ void adcStart(ADCDriver *adcp, const ADCConfig *config) {
chDbgCheck(adcp != NULL, "adcStart");
chSysLock();
- chDbgAssert((adcp->ad_state == ADC_STOP) || (adcp->ad_state == ADC_READY),
+ chDbgAssert((adcp->state == ADC_STOP) || (adcp->state == ADC_READY),
"adcStart(), #1", "invalid state");
- adcp->ad_config = config;
+ adcp->config = config;
adc_lld_start(adcp);
- adcp->ad_state = ADC_READY;
+ adcp->state = ADC_READY;
chSysUnlock();
}
@@ -121,10 +122,10 @@ void adcStop(ADCDriver *adcp) {
chDbgCheck(adcp != NULL, "adcStop");
chSysLock();
- chDbgAssert((adcp->ad_state == ADC_STOP) || (adcp->ad_state == ADC_READY),
+ chDbgAssert((adcp->state == ADC_STOP) || (adcp->state == ADC_READY),
"adcStop(), #1", "invalid state");
adc_lld_stop(adcp);
- adcp->ad_state = ADC_STOP;
+ adcp->state = ADC_STOP;
chSysUnlock();
}
@@ -179,13 +180,13 @@ void adcStartConversionI(ADCDriver *adcp,
((depth == 1) || ((depth & 1) == 0)),
"adcStartConversionI");
- chDbgAssert((adcp->ad_state == ADC_READY) ||
- (adcp->ad_state == ADC_COMPLETE),
+ chDbgAssert((adcp->state == ADC_READY) ||
+ (adcp->state == ADC_COMPLETE),
"adcStartConversionI(), #1", "not ready");
- adcp->ad_samples = samples;
- adcp->ad_depth = depth;
- adcp->ad_grpp = grpp;
- adcp->ad_state = ADC_ACTIVE;
+ adcp->samples = samples;
+ adcp->depth = depth;
+ adcp->grpp = grpp;
+ adcp->state = ADC_ACTIVE;
adc_lld_start_conversion(adcp);
}
@@ -204,13 +205,13 @@ void adcStopConversion(ADCDriver *adcp) {
chDbgCheck(adcp != NULL, "adcStopConversion");
chSysLock();
- chDbgAssert((adcp->ad_state == ADC_READY) ||
- (adcp->ad_state == ADC_ACTIVE),
+ chDbgAssert((adcp->state == ADC_READY) ||
+ (adcp->state == ADC_ACTIVE),
"adcStopConversion(), #1", "invalid state");
- if (adcp->ad_state != ADC_READY) {
+ if (adcp->state != ADC_READY) {
adc_lld_stop_conversion(adcp);
- adcp->ad_grpp = NULL;
- adcp->ad_state = ADC_READY;
+ adcp->grpp = NULL;
+ adcp->state = ADC_READY;
_adc_reset_s(adcp);
}
chSysUnlock();
@@ -230,14 +231,14 @@ void adcStopConversionI(ADCDriver *adcp) {
chDbgCheck(adcp != NULL, "adcStopConversionI");
- chDbgAssert((adcp->ad_state == ADC_READY) ||
- (adcp->ad_state == ADC_ACTIVE) ||
- (adcp->ad_state == ADC_COMPLETE),
+ chDbgAssert((adcp->state == ADC_READY) ||
+ (adcp->state == ADC_ACTIVE) ||
+ (adcp->state == ADC_COMPLETE),
"adcStopConversionI(), #1", "invalid state");
- if (adcp->ad_state != ADC_READY) {
+ if (adcp->state != ADC_READY) {
adc_lld_stop_conversion(adcp);
- adcp->ad_grpp = NULL;
- adcp->ad_state = ADC_READY;
+ adcp->grpp = NULL;
+ adcp->state = ADC_READY;
_adc_reset_i(adcp);
}
}
@@ -271,9 +272,9 @@ msg_t adcConvert(ADCDriver *adcp,
msg_t msg;
chSysLock();
- chDbgAssert(grpp->acg_endcb == NULL, "adcConvert(), #1", "has callback");
+ chDbgAssert(adcp->thread == NULL, "adcConvert(), #1", "already waiting");
adcStartConversionI(adcp, grpp, samples, depth);
- (adcp)->ad_thread = chThdSelf();
+ (adcp)->thread = chThdSelf();
chSchGoSleepS(THD_STATE_SUSPENDED);
msg = chThdSelf()->p_u.rdymsg;
chSysUnlock();
@@ -286,8 +287,8 @@ msg_t adcConvert(ADCDriver *adcp,
* @brief Gains exclusive access to the ADC peripheral.
* @details This function tries to gain ownership to the ADC bus, if the bus
* is already being used then the invoking thread is queued.
- * @pre In order to use this function the option @p ADC_USE_MUTUAL_EXCLUSION
- * must be enabled.
+ * @pre In order to use this function the option
+ * @p ADC_USE_MUTUAL_EXCLUSION must be enabled.
*
* @param[in] adcp pointer to the @p ADCDriver object
*
@@ -298,16 +299,16 @@ void adcAcquireBus(ADCDriver *adcp) {
chDbgCheck(adcp != NULL, "adcAcquireBus");
#if CH_USE_MUTEXES
- chMtxLock(&adcp->ad_mutex);
+ chMtxLock(&adcp->mutex);
#elif CH_USE_SEMAPHORES
- chSemWait(&adcp->ad_semaphore);
+ chSemWait(&adcp->semaphore);
#endif
}
/**
* @brief Releases exclusive access to the ADC peripheral.
- * @pre In order to use this function the option @p ADC_USE_MUTUAL_EXCLUSION
- * must be enabled.
+ * @pre In order to use this function the option
+ * @p ADC_USE_MUTUAL_EXCLUSION must be enabled.
*
* @param[in] adcp pointer to the @p ADCDriver object
*
@@ -321,7 +322,7 @@ void adcReleaseBus(ADCDriver *adcp) {
(void)adcp;
chMtxUnlock();
#elif CH_USE_SEMAPHORES
- chSemSignal(&adcp->ad_semaphore);
+ chSemSignal(&adcp->semaphore);
#endif
}
#endif /* ADC_USE_MUTUAL_EXCLUSION */
diff --git a/os/hal/src/can.c b/os/hal/src/can.c
index d63cbfd8a..f9a827c4e 100644
--- a/os/hal/src/can.c
+++ b/os/hal/src/can.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,17 +68,17 @@ void canInit(void) {
*/
void canObjectInit(CANDriver *canp) {
- canp->cd_state = CAN_STOP;
- canp->cd_config = NULL;
- chSemInit(&canp->cd_txsem, 0);
- chSemInit(&canp->cd_rxsem, 0);
- chEvtInit(&canp->cd_rxfull_event);
- chEvtInit(&canp->cd_txempty_event);
- chEvtInit(&canp->cd_error_event);
- canp->cd_status = 0;
+ canp->state = CAN_STOP;
+ canp->config = NULL;
+ chSemInit(&canp->txsem, 0);
+ chSemInit(&canp->rxsem, 0);
+ chEvtInit(&canp->rxfull_event);
+ chEvtInit(&canp->txempty_event);
+ chEvtInit(&canp->error_event);
+ canp->status = 0;
#if CAN_USE_SLEEP_MODE
- chEvtInit(&canp->cd_sleep_event);
- chEvtInit(&canp->cd_wakeup_event);
+ chEvtInit(&canp->sleep_event);
+ chEvtInit(&canp->wakeup_event);
#endif /* CAN_USE_SLEEP_MODE */
}
@@ -98,16 +99,16 @@ void canStart(CANDriver *canp, const CANConfig *config) {
chDbgCheck(canp != NULL, "canStart");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_STOP) ||
- (canp->cd_state == CAN_STARTING) ||
- (canp->cd_state == CAN_READY),
+ chDbgAssert((canp->state == CAN_STOP) ||
+ (canp->state == CAN_STARTING) ||
+ (canp->state == CAN_READY),
"canStart(), #1", "invalid state");
- while (canp->cd_state == CAN_STARTING)
+ while (canp->state == CAN_STARTING)
chThdSleepS(1);
- if (canp->cd_state == CAN_STOP) {
- canp->cd_config = config;
+ if (canp->state == CAN_STOP) {
+ canp->config = config;
can_lld_start(canp);
- canp->cd_state = CAN_READY;
+ canp->state = CAN_READY;
}
chSysUnlock();
}
@@ -124,14 +125,14 @@ void canStop(CANDriver *canp) {
chDbgCheck(canp != NULL, "canStop");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_STOP) || (canp->cd_state == CAN_READY),
+ chDbgAssert((canp->state == CAN_STOP) || (canp->state == CAN_READY),
"canStop(), #1", "invalid state");
can_lld_stop(canp);
- chSemResetI(&canp->cd_rxsem, 0);
- chSemResetI(&canp->cd_txsem, 0);
+ chSemResetI(&canp->rxsem, 0);
+ chSemResetI(&canp->txsem, 0);
chSchRescheduleS();
- canp->cd_state = CAN_STOP;
- canp->cd_status = 0;
+ canp->state = CAN_STOP;
+ canp->status = 0;
chSysUnlock();
}
@@ -142,7 +143,7 @@ void canStop(CANDriver *canp) {
* @note Trying to transmit while in sleep mode simply enqueues the thread.
*
* @param[in] canp pointer to the @p CANDriver object
- * @param[in] ctfp pointer to the CAN frame to be transmitted
+ * @param[in] ctfp pointer to the CAN frame to be transmitted
* @param[in] timeout the number of ticks before the operation timeouts,
* the following special values are allowed:
* - @a TIME_IMMEDIATE immediate timeout.
@@ -160,10 +161,10 @@ msg_t canTransmit(CANDriver *canp, const CANTxFrame *ctfp, systime_t timeout) {
chDbgCheck((canp != NULL) && (ctfp != NULL), "canTransmit");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
+ chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"canTransmit(), #1", "invalid state");
- while ((canp->cd_state == CAN_SLEEP) || !can_lld_can_transmit(canp)) {
- msg_t msg = chSemWaitTimeoutS(&canp->cd_txsem, timeout);
+ while ((canp->state == CAN_SLEEP) || !can_lld_can_transmit(canp)) {
+ msg_t msg = chSemWaitTimeoutS(&canp->txsem, timeout);
if (msg != RDY_OK) {
chSysUnlock();
return msg;
@@ -200,10 +201,10 @@ msg_t canReceive(CANDriver *canp, CANRxFrame *crfp, systime_t timeout) {
chDbgCheck((canp != NULL) && (crfp != NULL), "canReceive");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
+ chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"canReceive(), #1", "invalid state");
- while ((canp->cd_state == CAN_SLEEP) || !can_lld_can_receive(canp)) {
- msg_t msg = chSemWaitTimeoutS(&canp->cd_rxsem, timeout);
+ while ((canp->state == CAN_SLEEP) || !can_lld_can_receive(canp)) {
+ msg_t msg = chSemWaitTimeoutS(&canp->rxsem, timeout);
if (msg != RDY_OK) {
chSysUnlock();
return msg;
@@ -226,8 +227,8 @@ canstatus_t canGetAndClearFlags(CANDriver *canp) {
canstatus_t status;
chSysLock();
- status = canp->cd_status;
- canp->cd_status = 0;
+ status = canp->status;
+ canp->status = 0;
chSysUnlock();
return status;
}
@@ -236,7 +237,7 @@ canstatus_t canGetAndClearFlags(CANDriver *canp) {
/**
* @brief Enters the sleep mode.
* @details This function puts the CAN driver in sleep mode and broadcasts
- * the @p cd_sleep_event event source.
+ * the @p sleep_event event source.
* @pre In order to use this function the option @p CAN_USE_SLEEP_MODE must
* be enabled and the @p CAN_SUPPORTS_SLEEP mode must be supported
* by the low level driver.
@@ -250,12 +251,12 @@ void canSleep(CANDriver *canp) {
chDbgCheck(canp != NULL, "canSleep");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
+ chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"canSleep(), #1", "invalid state");
- if (canp->cd_state == CAN_READY) {
+ if (canp->state == CAN_READY) {
can_lld_sleep(canp);
- canp->cd_state = CAN_SLEEP;
- chEvtBroadcastI(&canp->cd_sleep_event);
+ canp->state = CAN_SLEEP;
+ chEvtBroadcastI(&canp->sleep_event);
chSchRescheduleS();
}
chSysUnlock();
@@ -273,12 +274,12 @@ void canWakeup(CANDriver *canp) {
chDbgCheck(canp != NULL, "canWakeup");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
+ chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"canWakeup(), #1", "invalid state");
- if (canp->cd_state == CAN_SLEEP) {
+ if (canp->state == CAN_SLEEP) {
can_lld_wakeup(canp);
- canp->cd_state = CAN_READY;
- chEvtBroadcastI(&canp->cd_wakeup_event);
+ canp->state = CAN_READY;
+ chEvtBroadcastI(&canp->wakeup_event);
chSchRescheduleS();
}
chSysUnlock();
diff --git a/os/hal/src/gpt.c b/os/hal/src/gpt.c
new file mode 100644
index 000000000..e90a8911a
--- /dev/null
+++ b/os/hal/src/gpt.c
@@ -0,0 +1,229 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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 gpt.c
+ * @brief GPT Driver code.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT Driver initialization.
+ * @note This function is implicitly invoked by @p halInit(), there is
+ * no need to explicitly initialize the driver.
+ *
+ * @init
+ */
+void gptInit(void) {
+
+ gpt_lld_init();
+}
+
+/**
+ * @brief Initializes the standard part of a @p GPTDriver structure.
+ *
+ * @param[out] gptp pointer to the @p GPTDriver object
+ *
+ * @init
+ */
+void gptObjectInit(GPTDriver *gptp) {
+
+ gptp->state = GPT_STOP;
+ gptp->config = NULL;
+}
+
+/**
+ * @brief Configures and activates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] config pointer to the @p GPTConfig object
+ *
+ * @api
+ */
+void gptStart(GPTDriver *gptp, const GPTConfig *config) {
+
+ chDbgCheck((gptp != NULL) && (config != NULL), "ptStart");
+
+ chSysLock();
+ chDbgAssert((gptp->state == GPT_STOP) || (gptp->state == GPT_READY),
+ "gptStart(), #1", "invalid state");
+ gptp->config = config;
+ gpt_lld_start(gptp);
+ gptp->state = GPT_READY;
+ chSysUnlock();
+}
+
+/**
+ * @brief Deactivates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @api
+ */
+void gptStop(GPTDriver *gptp) {
+
+ chDbgCheck(gptp != NULL, "gptStop");
+
+ chSysLock();
+ chDbgAssert((gptp->state == GPT_STOP) || (gptp->state == GPT_READY),
+ "gptStop(), #1", "invalid state");
+ gpt_lld_stop(gptp);
+ gptp->state = GPT_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @api
+ */
+void gptStartContinuous(GPTDriver *gptp, gptcnt_t interval) {
+
+ chSysLock();
+ gptStartContinuousI(gptp, interval);
+ chSysUnlock();
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @iclass
+ */
+void gptStartContinuousI(GPTDriver *gptp, gptcnt_t interval) {
+
+ chDbgAssert(gptp->state == GPT_READY,
+ "gptStartContinuousI(), #1", "invalid state");
+ gptp->state = GPT_CONTINUOUS;
+ gpt_lld_start_timer(gptp, interval);
+}
+
+/**
+ * @brief Starts the timer in one shot mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @api
+ */
+void gptStartOneShot(GPTDriver *gptp, gptcnt_t interval) {
+
+ chSysLock();
+ gptStartOneShotI(gptp, interval);
+ chSysUnlock();
+}
+
+/**
+ * @brief Starts the timer in one shot mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @api
+ */
+void gptStartOneShotI(GPTDriver *gptp, gptcnt_t interval) {
+
+ chDbgAssert(gptp->state == GPT_READY,
+ "gptStartOneShotI(), #1", "invalid state");
+ gptp->state = GPT_ONESHOT;
+ gpt_lld_start_timer(gptp, interval);
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @api
+ */
+void gptStopTimer(GPTDriver *gptp) {
+
+ chSysLock();
+ gptStopTimerI(gptp);
+ chSysUnlock();
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @api
+ */
+void gptStopTimerI(GPTDriver *gptp) {
+
+ chDbgAssert((gptp->state == GPT_READY) || (gptp->state == GPT_CONTINUOUS) ||
+ (gptp->state == GPT_ONESHOT),
+ "gptStopTimerI(), #1", "invalid state");
+ gptp->state = GPT_READY;
+ gpt_lld_stop_timer(gptp);
+}
+
+/**
+ * @brief Starts the timer in one shot mode and waits for completion.
+ * @details This function specifically polls the timer waiting for completion
+ * in order to not have extra delays caused by interrupt servicing,
+ * this function is only recommended for short delays.
+ * @note The configured callback is not invoked when using this function.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @api
+ */
+void gptPolledDelay(GPTDriver *gptp, gptcnt_t interval) {
+
+ chDbgAssert(gptp->state == GPT_READY,
+ "gptPolledDelay(), #1", "invalid state");
+ gptp->state = GPT_ONESHOT;
+ gpt_lld_polled_delay(gptp, interval);
+}
+
+#endif /* HAL_USE_GPT */
+
+/** @} */
diff --git a/os/hal/src/hal.c b/os/hal/src/hal.c
index bfbaa3e84..1a15988f5 100644
--- a/os/hal/src/hal.c
+++ b/os/hal/src/hal.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -66,9 +67,15 @@ void halInit(void) {
#if HAL_USE_CAN || defined(__DOXYGEN__)
canInit();
#endif
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+ gptInit();
+#endif
#if HAL_USE_I2C || defined(__DOXYGEN__)
i2cInit();
#endif
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+ icuInit();
+#endif
#if HAL_USE_MAC || defined(__DOXYGEN__)
macInit();
#endif
@@ -78,6 +85,9 @@ void halInit(void) {
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
sdInit();
#endif
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+ sdcInit();
+#endif
#if HAL_USE_SPI || defined(__DOXYGEN__)
spiInit();
#endif
diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c
index 84dfcf958..6f99a1afb 100644
--- a/os/hal/src/i2c.c
+++ b/os/hal/src/i2c.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/src/icu.c b/os/hal/src/icu.c
new file mode 100644
index 000000000..3be67448e
--- /dev/null
+++ b/os/hal/src/icu.c
@@ -0,0 +1,151 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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 icu.c
+ * @brief ICU Driver code.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief ICU Driver initialization.
+ * @note This function is implicitly invoked by @p halInit(), there is
+ * no need to explicitly initialize the driver.
+ *
+ * @init
+ */
+void icuInit(void) {
+
+ icu_lld_init();
+}
+
+/**
+ * @brief Initializes the standard part of a @p ICUDriver structure.
+ *
+ * @param[out] icup pointer to the @p ICUDriver object
+ *
+ * @init
+ */
+void icuObjectInit(ICUDriver *icup) {
+
+ icup->state = ICU_STOP;
+ icup->config = NULL;
+}
+
+/**
+ * @brief Configures and activates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @param[in] config pointer to the @p ICUConfig object
+ *
+ * @api
+ */
+void icuStart(ICUDriver *icup, const ICUConfig *config) {
+
+ chDbgCheck((icup != NULL) && (config != NULL), "icuStart");
+
+ chSysLock();
+ chDbgAssert((icup->state == ICU_STOP) || (icup->state == ICU_READY),
+ "icuStart(), #1", "invalid state");
+ icup->config = config;
+ icu_lld_start(icup);
+ icup->state = ICU_READY;
+ chSysUnlock();
+}
+
+/**
+ * @brief Deactivates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @api
+ */
+void icuStop(ICUDriver *icup) {
+
+ chDbgCheck(icup != NULL, "icuStop");
+
+ chSysLock();
+ chDbgAssert((icup->state == ICU_STOP) || (icup->state == ICU_READY),
+ "icuStop(), #1", "invalid state");
+ icu_lld_stop(icup);
+ icup->state = ICU_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Enables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @api
+ */
+void icuEnable(ICUDriver *icup) {
+
+ chSysLock();
+ chDbgAssert(icup->state == ICU_READY, "icuEnable(), #1", "invalid state");
+ icu_lld_enable(icup);
+ icup->state = ICU_WAITING;
+ chSysUnlock();
+}
+
+/**
+ * @brief Disables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @api
+ */
+void icuDisable(ICUDriver *icup) {
+
+ chSysLock();
+ chDbgAssert((icup->state == ICU_READY) || (icup->state == ICU_WAITING) ||
+ (icup->state == ICU_ACTIVE) || (icup->state == ICU_IDLE),
+ "icuDisable(), #1", "invalid state");
+ icu_lld_disable(icup);
+ icup->state = ICU_READY;
+ chSysUnlock();
+}
+
+#endif /* HAL_USE_ICU */
+
+/** @} */
diff --git a/os/hal/src/mac.c b/os/hal/src/mac.c
index 48656a8a3..4d6a9b2cd 100644
--- a/os/hal/src/mac.c
+++ b/os/hal/src/mac.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -71,10 +72,10 @@ void macInit(void) {
*/
void macObjectInit(MACDriver *macp) {
- chSemInit(&macp->md_tdsem, 0);
- chSemInit(&macp->md_rdsem, 0);
+ chSemInit(&macp->tdsem, 0);
+ chSemInit(&macp->rdsem, 0);
#if CH_USE_EVENTS
- chEvtInit(&macp->md_rdevent);
+ chEvtInit(&macp->rdevent);
#endif
}
@@ -123,8 +124,10 @@ msg_t macWaitTransmitDescriptor(MACDriver *macp,
(time > 0)) {
chSysLock();
systime_t now = chTimeNow();
- if ((msg = chSemWaitTimeoutS(&macp->md_tdsem, time)) == RDY_TIMEOUT)
+ if ((msg = chSemWaitTimeoutS(&macp->tdsem, time)) == RDY_TIMEOUT) {
+ chSysUnlock();
break;
+ }
if (time != TIME_INFINITE)
time -= (chTimeNow() - now);
chSysUnlock();
@@ -173,8 +176,10 @@ msg_t macWaitReceiveDescriptor(MACDriver *macp,
(time > 0)) {
chSysLock();
systime_t now = chTimeNow();
- if ((msg = chSemWaitTimeoutS(&macp->md_rdsem, time)) == RDY_TIMEOUT)
+ if ((msg = chSemWaitTimeoutS(&macp->rdsem, time)) == RDY_TIMEOUT) {
+ chSysUnlock();
break;
+ }
if (time != TIME_INFINITE)
time -= (chTimeNow() - now);
chSysUnlock();
diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c
index 1b2d930c5..e6dcf9287 100644
--- a/os/hal/src/mmc_spi.c
+++ b/os/hal/src/mmc_spi.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -18,7 +19,7 @@
*/
/**
- * @file mmc_spi.c
+ * @file spi.c
* @brief MMC over SPI driver code.
*
* @addtogroup MMC_SPI
@@ -52,24 +53,24 @@
static void tmrfunc(void *p) {
MMCDriver *mmcp = p;
- if (mmcp->mmc_cnt > 0) {
- if (mmcp->mmc_is_inserted()) {
- if (--mmcp->mmc_cnt == 0) {
- mmcp->mmc_state = MMC_INSERTED;
- chEvtBroadcastI(&mmcp->mmc_inserted_event);
+ if (mmcp->cnt > 0) {
+ if (mmcp->is_inserted()) {
+ if (--mmcp->cnt == 0) {
+ mmcp->state = MMC_INSERTED;
+ chEvtBroadcastI(&mmcp->inserted_event);
}
}
else
- mmcp->mmc_cnt = MMC_POLLING_INTERVAL;
+ mmcp->cnt = MMC_POLLING_INTERVAL;
}
else {
- if (!mmcp->mmc_is_inserted()) {
- mmcp->mmc_state = MMC_WAIT;
- mmcp->mmc_cnt = MMC_POLLING_INTERVAL;
- chEvtBroadcastI(&mmcp->mmc_removed_event);
+ if (!mmcp->is_inserted()) {
+ mmcp->state = MMC_WAIT;
+ mmcp->cnt = MMC_POLLING_INTERVAL;
+ chEvtBroadcastI(&mmcp->removed_event);
}
}
- chVTSetI(&mmcp->mmc_vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
+ chVTSetI(&mmcp->vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
}
/**
@@ -84,13 +85,13 @@ static void wait(MMCDriver *mmcp) {
uint8_t buf[4];
for (i = 0; i < 16; i++) {
- spiReceive(mmcp->mmc_spip, 1, buf);
+ spiReceive(mmcp->spip, 1, buf);
if (buf[0] == 0xFF)
break;
}
/* Looks like it is a long wait.*/
while (TRUE) {
- spiReceive(mmcp->mmc_spip, 1, buf);
+ spiReceive(mmcp->spip, 1, buf);
if (buf[0] == 0xFF)
break;
#ifdef MMC_NICE_WAITING
@@ -121,7 +122,7 @@ static void send_hdr(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) {
buf[3] = arg >> 8;
buf[4] = arg;
buf[5] = 0x95; /* Valid for CMD0 ignored by other commands. */
- spiSend(mmcp->mmc_spip, 6, buf);
+ spiSend(mmcp->spip, 6, buf);
}
/**
@@ -138,7 +139,7 @@ static uint8_t recvr1(MMCDriver *mmcp) {
uint8_t r1[1];
for (i = 0; i < 9; i++) {
- spiReceive(mmcp->mmc_spip, 1, r1);
+ spiReceive(mmcp->spip, 1, r1);
if (r1[0] != 0xFF)
return r1[0];
}
@@ -159,10 +160,10 @@ static uint8_t recvr1(MMCDriver *mmcp) {
static uint8_t send_command(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) {
uint8_t r1;
- spiSelect(mmcp->mmc_spip);
+ spiSelect(mmcp->spip);
send_hdr(mmcp, cmd, arg);
r1 = recvr1(mmcp);
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
return r1;
}
@@ -176,16 +177,16 @@ static uint8_t send_command(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) {
static void sync(MMCDriver *mmcp) {
uint8_t buf[1];
- spiSelect(mmcp->mmc_spip);
+ spiSelect(mmcp->spip);
while (TRUE) {
- spiReceive(mmcp->mmc_spip, 1, buf);
+ spiReceive(mmcp->spip, 1, buf);
if (buf[0] == 0xFF)
break;
#ifdef MMC_NICE_WAITING
chThdSleep(1); /* Trying to be nice with the other threads.*/
#endif
}
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
}
/*===========================================================================*/
@@ -221,15 +222,15 @@ void mmcObjectInit(MMCDriver *mmcp, SPIDriver *spip,
const SPIConfig *lscfg, const SPIConfig *hscfg,
mmcquery_t is_protected, mmcquery_t is_inserted) {
- mmcp->mmc_state = MMC_STOP;
- mmcp->mmc_config = NULL;
- mmcp->mmc_spip = spip;
- mmcp->mmc_lscfg = lscfg;
- mmcp->mmc_hscfg = hscfg;
- mmcp->mmc_is_protected = is_protected;
- mmcp->mmc_is_inserted = is_inserted;
- chEvtInit(&mmcp->mmc_inserted_event);
- chEvtInit(&mmcp->mmc_removed_event);
+ mmcp->state = MMC_STOP;
+ mmcp->config = NULL;
+ mmcp->spip = spip;
+ mmcp->lscfg = lscfg;
+ mmcp->hscfg = hscfg;
+ mmcp->is_protected = is_protected;
+ mmcp->is_inserted = is_inserted;
+ chEvtInit(&mmcp->inserted_event);
+ chEvtInit(&mmcp->removed_event);
}
/**
@@ -245,11 +246,11 @@ void mmcStart(MMCDriver *mmcp, const MMCConfig *config) {
chDbgCheck((mmcp != NULL) && (config == NULL), "mmcStart");
chSysLock();
- chDbgAssert(mmcp->mmc_state == MMC_STOP, "mmcStart(), #1", "invalid state");
- mmcp->mmc_config = config;
- mmcp->mmc_state = MMC_WAIT;
- mmcp->mmc_cnt = MMC_POLLING_INTERVAL;
- chVTSetI(&mmcp->mmc_vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
+ chDbgAssert(mmcp->state == MMC_STOP, "mmcStart(), #1", "invalid state");
+ mmcp->config = config;
+ mmcp->state = MMC_WAIT;
+ mmcp->cnt = MMC_POLLING_INTERVAL;
+ chVTSetI(&mmcp->vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
chSysUnlock();
}
@@ -265,17 +266,16 @@ void mmcStop(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcStop");
chSysLock();
- chDbgAssert((mmcp->mmc_state != MMC_UNINIT) &&
- (mmcp->mmc_state != MMC_READING) &&
- (mmcp->mmc_state != MMC_WRITING),
- "mmcStop(), #1",
- "invalid state");
- if (mmcp->mmc_state != MMC_STOP) {
- mmcp->mmc_state = MMC_STOP;
- chVTResetI(&mmcp->mmc_vt);
+ chDbgAssert((mmcp->state != MMC_UNINIT) &&
+ (mmcp->state != MMC_READING) &&
+ (mmcp->state != MMC_WRITING),
+ "mmcStop(), #1", "invalid state");
+ if (mmcp->state != MMC_STOP) {
+ mmcp->state = MMC_STOP;
+ chVTResetI(&mmcp->vt);
}
chSysUnlock();
- spiStop(mmcp->mmc_spip);
+ spiStop(mmcp->spip);
}
/**
@@ -300,15 +300,13 @@ bool_t mmcConnect(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcConnect");
- chDbgAssert((mmcp->mmc_state != MMC_UNINIT) &&
- (mmcp->mmc_state != MMC_STOP),
- "mmcConnect(), #1",
- "invalid state");
+ chDbgAssert((mmcp->state != MMC_UNINIT) && (mmcp->state != MMC_STOP),
+ "mmcConnect(), #1", "invalid state");
- if (mmcp->mmc_state == MMC_INSERTED) {
+ if (mmcp->state == MMC_INSERTED) {
/* Slow clock mode and 128 clock pulses.*/
- spiStart(mmcp->mmc_spip, mmcp->mmc_lscfg);
- spiIgnore(mmcp->mmc_spip, 16);
+ spiStart(mmcp->spip, mmcp->lscfg);
+ spiIgnore(mmcp->spip, 16);
/* SPI mode selection.*/
i = 0;
@@ -334,7 +332,7 @@ bool_t mmcConnect(MMCDriver *mmcp) {
}
/* Initialization complete, full speed. */
- spiStart(mmcp->mmc_spip, mmcp->mmc_hscfg);
+ spiStart(mmcp->spip, mmcp->hscfg);
/* Setting block size.*/
if (send_command(mmcp, MMC_CMDSETBLOCKLEN, MMC_SECTOR_SIZE) != 0x00)
@@ -342,8 +340,8 @@ bool_t mmcConnect(MMCDriver *mmcp) {
/* Transition to MMC_READY state (if not extracted).*/
chSysLock();
- if (mmcp->mmc_state == MMC_INSERTED) {
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_INSERTED) {
+ mmcp->state = MMC_READY;
result = FALSE;
}
else
@@ -351,7 +349,7 @@ bool_t mmcConnect(MMCDriver *mmcp) {
chSysUnlock();
return result;
}
- if (mmcp->mmc_state == MMC_READY)
+ if (mmcp->state == MMC_READY)
return FALSE;
/* Any other state is invalid.*/
return TRUE;
@@ -373,24 +371,22 @@ bool_t mmcDisconnect(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcDisconnect");
- chDbgAssert((mmcp->mmc_state != MMC_UNINIT) &&
- (mmcp->mmc_state != MMC_STOP),
- "mmcDisconnect(), #1",
- "invalid state");
- switch (mmcp->mmc_state) {
+ chDbgAssert((mmcp->state != MMC_UNINIT) && (mmcp->state != MMC_STOP),
+ "mmcDisconnect(), #1", "invalid state");
+ switch (mmcp->state) {
case MMC_READY:
/* Wait for the pending write operations to complete.*/
sync(mmcp);
chSysLock();
- if (mmcp->mmc_state == MMC_READY)
- mmcp->mmc_state = MMC_INSERTED;
+ if (mmcp->state == MMC_READY)
+ mmcp->state = MMC_INSERTED;
chSysUnlock();
case MMC_INSERTED:
status = FALSE;
default:
status = TRUE;
}
- spiStop(mmcp->mmc_spip);
+ spiStop(mmcp->spip);
return status;
}
@@ -410,21 +406,21 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) {
chDbgCheck(mmcp != NULL, "mmcStartSequentialRead");
chSysLock();
- if (mmcp->mmc_state != MMC_READY) {
+ if (mmcp->state != MMC_READY) {
chSysUnlock();
return TRUE;
}
- mmcp->mmc_state = MMC_READING;
+ mmcp->state = MMC_READING;
chSysUnlock();
- spiStart(mmcp->mmc_spip, mmcp->mmc_hscfg);
- spiSelect(mmcp->mmc_spip);
+ spiStart(mmcp->spip, mmcp->hscfg);
+ spiSelect(mmcp->spip);
send_hdr(mmcp, MMC_CMDREADMULTIPLE, startblk * MMC_SECTOR_SIZE);
if (recvr1(mmcp) != 0x00) {
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_READING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_READING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return TRUE;
}
@@ -448,26 +444,26 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialRead");
chSysLock();
- if (mmcp->mmc_state != MMC_READING) {
+ if (mmcp->state != MMC_READING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
for (i = 0; i < MMC_WAIT_DATA; i++) {
- spiReceive(mmcp->mmc_spip, 1, buffer);
+ spiReceive(mmcp->spip, 1, buffer);
if (buffer[0] == 0xFE) {
- spiReceive(mmcp->mmc_spip, MMC_SECTOR_SIZE, buffer);
+ spiReceive(mmcp->spip, MMC_SECTOR_SIZE, buffer);
/* CRC ignored. */
- spiIgnore(mmcp->mmc_spip, 2);
+ spiIgnore(mmcp->spip, 2);
return FALSE;
}
}
/* Timeout.*/
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_READING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_READING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return TRUE;
}
@@ -489,22 +485,22 @@ bool_t mmcStopSequentialRead(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcStopSequentialRead");
chSysLock();
- if (mmcp->mmc_state != MMC_READING) {
+ if (mmcp->state != MMC_READING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
- spiSend(mmcp->mmc_spip, sizeof(stopcmd), stopcmd);
+ spiSend(mmcp->spip, sizeof(stopcmd), stopcmd);
/* result = recvr1(mmcp) != 0x00;*/
/* Note, ignored r1 response, it can be not zero, unknown issue.*/
recvr1(mmcp);
result = FALSE;
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_READING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_READING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return result;
}
@@ -525,21 +521,21 @@ bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) {
chDbgCheck(mmcp != NULL, "mmcStartSequentialWrite");
chSysLock();
- if (mmcp->mmc_state != MMC_READY) {
+ if (mmcp->state != MMC_READY) {
chSysUnlock();
return TRUE;
}
- mmcp->mmc_state = MMC_WRITING;
+ mmcp->state = MMC_WRITING;
chSysUnlock();
- spiStart(mmcp->mmc_spip, mmcp->mmc_hscfg);
- spiSelect(mmcp->mmc_spip);
+ spiStart(mmcp->spip, mmcp->hscfg);
+ spiSelect(mmcp->spip);
send_hdr(mmcp, MMC_CMDWRITEMULTIPLE, startblk * MMC_SECTOR_SIZE);
if (recvr1(mmcp) != 0x00) {
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_WRITING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_WRITING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return TRUE;
}
@@ -564,26 +560,26 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) {
chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialWrite");
chSysLock();
- if (mmcp->mmc_state != MMC_WRITING) {
+ if (mmcp->state != MMC_WRITING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
- spiSend(mmcp->mmc_spip, sizeof(start), start); /* Data prologue. */
- spiSend(mmcp->mmc_spip, MMC_SECTOR_SIZE, buffer); /* Data. */
- spiIgnore(mmcp->mmc_spip, 2); /* CRC ignored. */
- spiReceive(mmcp->mmc_spip, 1, b);
+ spiSend(mmcp->spip, sizeof(start), start); /* Data prologue. */
+ spiSend(mmcp->spip, MMC_SECTOR_SIZE, buffer); /* Data. */
+ spiIgnore(mmcp->spip, 2); /* CRC ignored. */
+ spiReceive(mmcp->spip, 1, b);
if ((b[0] & 0x1F) == 0x05) {
wait(mmcp);
return FALSE;
}
/* Error.*/
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_WRITING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_WRITING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return TRUE;
}
@@ -604,18 +600,18 @@ bool_t mmcStopSequentialWrite(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcStopSequentialWrite");
chSysLock();
- if (mmcp->mmc_state != MMC_WRITING) {
+ if (mmcp->state != MMC_WRITING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
- spiSend(mmcp->mmc_spip, sizeof(stop), stop);
- spiUnselect(mmcp->mmc_spip);
+ spiSend(mmcp->spip, sizeof(stop), stop);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_WRITING) {
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_WRITING) {
+ mmcp->state = MMC_READY;
chSysUnlock();
return FALSE;
}
diff --git a/os/hal/src/pal.c b/os/hal/src/pal.c
index ce7c226e9..534935a55 100644
--- a/os/hal/src/pal.c
+++ b/os/hal/src/pal.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -64,9 +65,9 @@
ioportmask_t palReadBus(IOBus *bus) {
chDbgCheck((bus != NULL) &&
- (bus->bus_offset > PAL_IOPORTS_WIDTH), "palReadBus");
+ (bus->offset < PAL_IOPORTS_WIDTH), "palReadBus");
- return palReadGroup(bus->bus_portid, bus->bus_mask, bus->bus_offset);
+ return palReadGroup(bus->portid, bus->mask, bus->offset);
}
/**
@@ -89,9 +90,9 @@ ioportmask_t palReadBus(IOBus *bus) {
void palWriteBus(IOBus *bus, ioportmask_t bits) {
chDbgCheck((bus != NULL) &&
- (bus->bus_offset > PAL_IOPORTS_WIDTH), "palWriteBus");
+ (bus->offset < PAL_IOPORTS_WIDTH), "palWriteBus");
- palWriteGroup(bus->bus_portid, bus->bus_mask, bus->bus_offset, bits);
+ palWriteGroup(bus->portid, bus->mask, bus->offset, bits);
}
/**
@@ -112,9 +113,9 @@ void palWriteBus(IOBus *bus, ioportmask_t bits) {
void palSetBusMode(IOBus *bus, uint_fast8_t mode) {
chDbgCheck((bus != NULL) &&
- (bus->bus_offset > PAL_IOPORTS_WIDTH), "palSetBusMode");
+ (bus->offset < PAL_IOPORTS_WIDTH), "palSetBusMode");
- palSetGroupMode(bus->bus_portid, bus->bus_mask, mode);
+ palSetGroupMode(bus->portid, bus->mask, mode);
}
#endif /* HAL_USE_PAL */
diff --git a/os/hal/src/pwm.c b/os/hal/src/pwm.c
index cf619e508..e7dd6b64c 100644
--- a/os/hal/src/pwm.c
+++ b/os/hal/src/pwm.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,8 +68,8 @@ void pwmInit(void) {
*/
void pwmObjectInit(PWMDriver *pwmp) {
- pwmp->pd_state = PWM_STOP;
- pwmp->pd_config = NULL;
+ pwmp->state = PWM_STOP;
+ pwmp->config = NULL;
#if defined(PWM_DRIVER_EXT_INIT_HOOK)
PWM_DRIVER_EXT_INIT_HOOK(pwmp);
#endif
@@ -76,6 +77,8 @@ void pwmObjectInit(PWMDriver *pwmp) {
/**
* @brief Configures and activates the PWM peripheral.
+ * @note Starting a driver that is already in the @p PWM_READY state
+ * disables all the active channels.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] config pointer to a @p PWMConfig object
@@ -87,11 +90,12 @@ void pwmStart(PWMDriver *pwmp, const PWMConfig *config) {
chDbgCheck((pwmp != NULL) && (config != NULL), "pwmStart");
chSysLock();
- chDbgAssert((pwmp->pd_state == PWM_STOP) || (pwmp->pd_state == PWM_READY),
+ chDbgAssert((pwmp->state == PWM_STOP) || (pwmp->state == PWM_READY),
"pwmStart(), #1", "invalid state");
- pwmp->pd_config = config;
+ pwmp->config = config;
+ pwmp->period = config->period;
pwm_lld_start(pwmp);
- pwmp->pd_state = PWM_READY;
+ pwmp->state = PWM_READY;
chSysUnlock();
}
@@ -107,16 +111,46 @@ void pwmStop(PWMDriver *pwmp) {
chDbgCheck(pwmp != NULL, "pwmStop");
chSysLock();
- chDbgAssert((pwmp->pd_state == PWM_STOP) || (pwmp->pd_state == PWM_READY),
+ chDbgAssert((pwmp->state == PWM_STOP) || (pwmp->state == PWM_READY),
"pwmStop(), #1", "invalid state");
pwm_lld_stop(pwmp);
- pwmp->pd_state = PWM_STOP;
+ pwmp->state = PWM_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Changes the period the PWM peripheral.
+ * @details This function changes the period of a PWM unit that has already
+ * been activated using @p pwmStart().
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The PWM unit period is changed to the new value.
+ * @note If a period is specified that is shorter than the pulse width
+ * programmed in one of the channels then the behavior is not
+ * guaranteed.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] period new cycle time in ticks
+ *
+ * @api
+ */
+void pwmChangePeriod(PWMDriver *pwmp, pwmcnt_t period) {
+
+ chDbgCheck(pwmp != NULL, "pwmChangePeriod");
+
+ chSysLock();
+ chDbgAssert(pwmp->state == PWM_READY,
+ "pwmChangePeriod(), #1", "invalid state");
+ pwmChangePeriodI(pwmp, period);
chSysUnlock();
}
/**
* @brief Enables a PWM channel.
- * @details Programs (or reprograms) a PWM channel.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is active using the specified configuration.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
@@ -132,7 +166,7 @@ void pwmEnableChannel(PWMDriver *pwmp,
"pwmEnableChannel");
chSysLock();
- chDbgAssert(pwmp->pd_state == PWM_READY,
+ chDbgAssert(pwmp->state == PWM_READY,
"pwmEnableChannel(), #1", "not ready");
pwm_lld_enable_channel(pwmp, channel, width);
chSysUnlock();
@@ -140,8 +174,12 @@ void pwmEnableChannel(PWMDriver *pwmp,
/**
* @brief Disables a PWM channel.
- * @details The channel is disabled and its output line returned to the
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is disabled and its output line returned to the
* idle state.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
@@ -154,7 +192,7 @@ void pwmDisableChannel(PWMDriver *pwmp, pwmchannel_t channel) {
"pwmEnableChannel");
chSysLock();
- chDbgAssert(pwmp->pd_state == PWM_READY,
+ chDbgAssert(pwmp->state == PWM_READY,
"pwmDisableChannel(), #1", "not ready");
pwm_lld_disable_channel(pwmp, channel);
chSysUnlock();
diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c
new file mode 100644
index 000000000..283a0ee75
--- /dev/null
+++ b/os/hal/src/sdc.c
@@ -0,0 +1,392 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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 sdc.c
+ * @brief SDC Driver code.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Wait for the card to complete pending operations.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The operation status.
+ * @retval FALSE the card is now in transfer state.
+ * @retval TRUE an error occurred while waiting or the card is in an
+ * unexpected state.
+ *
+ * @notapi
+ */
+bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp) {
+ uint32_t resp[1];
+
+ while (TRUE) {
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_STATUS,
+ sdcp->rca, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ return TRUE;
+ switch (SDC_R1_STS(resp[0])) {
+ case SDC_STS_TRAN:
+ return FALSE;
+ case SDC_STS_DATA:
+ case SDC_STS_RCV:
+ case SDC_STS_PRG:
+#if SDC_NICE_WAITING
+ chThdSleepMilliseconds(1);
+#endif
+ continue;
+ default:
+ /* The card should have been initialized so any other state is not
+ valid and is reported as an error.*/
+ return TRUE;
+ }
+ }
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief SDC Driver initialization.
+ * @note This function is implicitly invoked by @p halInit(), there is
+ * no need to explicitly initialize the driver.
+ *
+ * @init
+ */
+void sdcInit(void) {
+
+ sdc_lld_init();
+}
+
+/**
+ * @brief Initializes the standard part of a @p SDCDriver structure.
+ *
+ * @param[out] sdcp pointer to the @p SDCDriver object
+ *
+ * @init
+ */
+void sdcObjectInit(SDCDriver *sdcp) {
+
+ sdcp->state = SDC_STOP;
+ sdcp->config = NULL;
+}
+
+/**
+ * @brief Configures and activates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] config pointer to the @p SDCConfig object, can be @p NULL if
+ * the driver supports a default configuration or
+ * requires no configuration
+ *
+ * @api
+ */
+void sdcStart(SDCDriver *sdcp, const SDCConfig *config) {
+
+ chDbgCheck(sdcp != NULL, "sdcStart");
+
+ chSysLock();
+ chDbgAssert((sdcp->state == SDC_STOP) || (sdcp->state == SDC_READY),
+ "sdcStart(), #1", "invalid state");
+ sdcp->config = config;
+ sdc_lld_start(sdcp);
+ sdcp->state = SDC_READY;
+ chSysUnlock();
+}
+
+/**
+ * @brief Deactivates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @api
+ */
+void sdcStop(SDCDriver *sdcp) {
+
+ chDbgCheck(sdcp != NULL, "sdcStop");
+
+ chSysLock();
+ chDbgAssert((sdcp->state == SDC_STOP) || (sdcp->state == SDC_READY),
+ "sdcStop(), #1", "invalid state");
+ sdc_lld_stop(sdcp);
+ sdcp->state = SDC_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Performs the initialization procedure on the inserted card.
+ * @details This function should be invoked when a card is inserted and
+ * brings the driver in the @p SDC_ACTIVE state where it is possible
+ * to perform read and write operations.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the driver is now
+ * in the @p SDC_ACTIVE state.
+ * @retval TRUE operation failed.
+ *
+ * @api
+ */
+bool_t sdcConnect(SDCDriver *sdcp) {
+ uint32_t resp[1];
+
+ chDbgCheck(sdcp != NULL, "sdcConnect");
+
+ chSysLock();
+ chDbgAssert((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE),
+ "mmcConnect(), #1", "invalid state");
+ sdcp->state = SDC_CONNECTING;
+ chSysUnlock();
+
+ /* Card clock initialization.*/
+ sdc_lld_start_clk(sdcp);
+
+ /* Enforces the initial card state.*/
+ sdc_lld_send_cmd_none(sdcp, SDC_CMD_GO_IDLE_STATE, 0);
+
+ /* V2.0 cards detection.*/
+ if (!sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_IF_COND,
+ SDC_CMD8_PATTERN, resp))
+ sdcp->cardmode = SDC_MODE_CARDTYPE_SDV20;
+ /* Voltage verification.*/
+ if (((resp[0] >> 8) & 0xF) != 1)
+ goto failed;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+ else {
+#if SDC_MMC_SUPPORT
+ /* MMC or SD V1.1 detection.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ sdcp->cardmode = SDC_MODE_CARDTYPE_MMC;
+ else
+#endif /* SDC_MMC_SUPPORT */
+ sdcp->cardmode = SDC_MODE_CARDTYPE_SDV11;
+ }
+
+#if SDC_MMC_SUPPORT
+ if ((sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_MMC) {
+ /* TODO: MMC initialization.*/
+ return TRUE;
+ }
+ else
+#endif /* SDC_MMC_SUPPORT */
+ {
+ unsigned i;
+ uint32_t ocr;
+
+ /* SD initialization.*/
+ if ((sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_SDV20)
+ ocr = 0xC0100000;
+ else
+ ocr = 0x80100000;
+
+ /* SD-type initialization. */
+ i = 0;
+ while (TRUE) {
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+ if (sdc_lld_send_cmd_short(sdcp, SDC_CMD_APP_OP_COND, ocr, resp))
+ goto failed;
+ if ((resp[0] & 0x80000000) != 0) {
+ if (resp[0] & 0x40000000)
+ sdcp->cardmode |= SDC_MODE_HIGH_CAPACITY;
+ break;
+ }
+ if (++i >= SDC_INIT_RETRY)
+ goto failed;
+ chThdSleepMilliseconds(10);
+ }
+ }
+
+ /* Reads CID.*/
+ if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_ALL_SEND_CID, 0, sdcp->cid))
+ goto failed;
+
+ /* Asks for the RCA.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_RELATIVE_ADDR,
+ 0, &sdcp->rca))
+ goto failed;
+
+ /* Reads CSD.*/
+ if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_SEND_CSD, sdcp->rca, sdcp->csd))
+ goto failed;
+
+ /* Switches to high speed.*/
+ sdc_lld_set_data_clk(sdcp);
+
+ /* Selects the card for operations.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEL_DESEL_CARD,
+ sdcp->rca, resp))
+ goto failed;
+
+ /* Block length fixed at 512 bytes.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BLOCKLEN,
+ SDC_BLOCK_SIZE, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+
+ /* Switches to wide bus mode.*/
+ switch (sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) {
+ case SDC_MODE_CARDTYPE_SDV11:
+ case SDC_MODE_CARDTYPE_SDV20:
+ sdc_lld_set_bus_mode(sdcp, SDC_MODE_4BIT);
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, sdcp->rca, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BUS_WIDTH, 2, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+ }
+
+ sdcp->state = SDC_ACTIVE;
+ return FALSE;
+failed:
+ sdc_lld_stop_clk(sdcp);
+ sdcp->state = SDC_READY;
+ return TRUE;
+}
+
+/**
+ * @brief Brings the driver in a state safe for card removal.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The operation status.
+ * @retval FALSE the operation succeeded and the driver is now
+ * in the @p SDC_READY state.
+ * @retval TRUE the operation failed.
+ *
+ * @api
+ */
+bool_t sdcDisconnect(SDCDriver *sdcp) {
+
+ chDbgCheck(sdcp != NULL, "sdcDisconnect");
+
+ chSysLock();
+ chDbgAssert(sdcp->state == SDC_ACTIVE,
+ "sdcDisconnect(), #1", "invalid state");
+ if (sdcp->state == SDC_READY) {
+ chSysUnlock();
+ return FALSE;
+ }
+ sdcp->state = SDC_DISCONNECTING;
+ chSysUnlock();
+
+ /* Waits for eventual pending operations completion.*/
+ if (sdc_wait_for_transfer_state(sdcp))
+ return TRUE;
+
+ /* Card clock stopped.*/
+ sdc_lld_stop_clk(sdcp);
+
+ sdcp->state = SDC_READY;
+ return FALSE;
+}
+
+/**
+ * @brief Reads one or more blocks.
+ * @pre The driver must be in the @p SDC_ACTIVE state after a successful
+ * sdcConnect() invocation.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer
+ * @param[in] n number of blocks to read
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * read.
+ * @retval TRUE operation failed, the state of the buffer is uncertain.
+ *
+ * @api
+ */
+bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t n) {
+ bool_t err;
+
+ chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcRead");
+
+ chSysLock();
+ chDbgAssert(sdcp->state == SDC_ACTIVE, "sdcRead(), #1", "invalid state");
+ sdcp->state = SDC_READING;
+ chSysUnlock();
+
+ err = sdc_lld_read(sdcp, startblk, buf, n);
+ sdcp->state = SDC_ACTIVE;
+ return err;
+}
+
+/**
+ * @brief Writes one or more blocks.
+ * @pre The driver must be in the @p SDC_ACTIVE state after a successful
+ * sdcConnect() invocation.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer
+ * @param[in] n number of blocks to write
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * written.
+ * @retval TRUE operation failed.
+ *
+ * @api
+ */
+bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t n) {
+ bool_t err;
+
+ chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcWrite");
+
+ chSysLock();
+ chDbgAssert(sdcp->state == SDC_ACTIVE, "sdcWrite(), #1", "invalid state");
+ sdcp->state = SDC_WRITING;
+ chSysUnlock();
+
+ err = sdc_lld_write(sdcp, startblk, buf, n);
+ sdcp->state = SDC_ACTIVE;
+ return err;
+}
+
+#endif /* HAL_USE_SDC */
+
+/** @} */
diff --git a/os/hal/src/serial.c b/os/hal/src/serial.c
index aafedcc6b..414689aac 100644
--- a/os/hal/src/serial.c
+++ b/os/hal/src/serial.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c
index 62a901162..3f53d7df0 100644
--- a/os/hal/src/serial_usb.c
+++ b/os/hal/src/serial_usb.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -58,44 +59,44 @@ static cdc_linecoding_t linecoding = {
static size_t writes(void *ip, const uint8_t *bp, size_t n) {
- return chOQWriteTimeout(&((SerialDriver *)ip)->oqueue, bp,
+ return chOQWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, bp,
n, TIME_INFINITE);
}
static size_t reads(void *ip, uint8_t *bp, size_t n) {
- return chIQReadTimeout(&((SerialDriver *)ip)->iqueue, bp,
+ return chIQReadTimeout(&((SerialUSBDriver *)ip)->iqueue, bp,
n, TIME_INFINITE);
}
static bool_t putwouldblock(void *ip) {
- return chOQIsFullI(&((SerialDriver *)ip)->oqueue);
+ return chOQIsFullI(&((SerialUSBDriver *)ip)->oqueue);
}
static bool_t getwouldblock(void *ip) {
- return chIQIsEmptyI(&((SerialDriver *)ip)->iqueue);
+ return chIQIsEmptyI(&((SerialUSBDriver *)ip)->iqueue);
}
static msg_t putt(void *ip, uint8_t b, systime_t timeout) {
- return chOQPutTimeout(&((SerialDriver *)ip)->oqueue, b, timeout);
+ return chOQPutTimeout(&((SerialUSBDriver *)ip)->oqueue, b, timeout);
}
static msg_t gett(void *ip, systime_t timeout) {
- return chIQGetTimeout(&((SerialDriver *)ip)->iqueue, timeout);
+ return chIQGetTimeout(&((SerialUSBDriver *)ip)->iqueue, timeout);
}
static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t time) {
- return chOQWriteTimeout(&((SerialDriver *)ip)->oqueue, bp, n, time);
+ return chOQWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, bp, n, time);
}
static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t time) {
- return chIQReadTimeout(&((SerialDriver *)ip)->iqueue, bp, n, time);
+ return chIQReadTimeout(&((SerialUSBDriver *)ip)->iqueue, bp, n, time);
}
static ioflags_t getflags(void *ip) {
@@ -119,11 +120,14 @@ static void inotify(GenericQueue *qp) {
emptied, then a whole packet is loaded in the queue.*/
if (chIQIsEmptyI(&sdup->iqueue)) {
- n = usbReadI(sdup->config->usbp, sdup->config->data_available_ep,
- sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
- if (n > 0) {
+ n = usbReadPacketI(sdup->config->usbp, DATA_AVAILABLE_EP,
+ sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
+ if (n != USB_ENDPOINT_BUSY) {
+ chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
- chSemSetCounterI(&sdup->iqueue.q_sem, n);
+ sdup->iqueue.q_counter = n;
+ while (notempty(&sdup->iqueue.q_waiting))
+ chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
}
@@ -133,15 +137,19 @@ static void inotify(GenericQueue *qp) {
*/
static void onotify(GenericQueue *qp) {
SerialUSBDriver *sdup = (SerialUSBDriver *)qp->q_rdptr;
- size_t n;
+ size_t w, n;
/* If there is any data in the output queue then it is sent within a
single packet and the queue is emptied.*/
- n = usbWriteI(sdup->config->usbp, sdup->config->data_request_ep,
- sdup->oqueue.q_buffer, chOQGetFullI(&sdup->oqueue));
- if (n > 0) {
+ n = chOQGetFullI(&sdup->oqueue);
+ w = usbWritePacketI(sdup->config->usbp, DATA_REQUEST_EP,
+ sdup->oqueue.q_buffer, n);
+ if (w != USB_ENDPOINT_BUSY) {
+ chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
- chSemSetCounterI(&sdup->oqueue.q_sem, SERIAL_USB_BUFFERS_SIZE);
+ sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue);
+ while (notempty(&sdup->oqueue.q_waiting))
+ chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
@@ -165,12 +173,6 @@ void sduInit(void) {
* outside, usually in the hardware initialization code.
*
* @param[out] sdup pointer to a @p SerialUSBDriver structure
- * @param[in] inotify pointer to a callback function that is invoked when
- * some data is read from the Queue. The value can be
- * @p NULL.
- * @param[in] onotify pointer to a callback function that is invoked when
- * some data is written in the Queue. The value can be
- * @p NULL.
*
* @init
*/
@@ -206,7 +208,7 @@ void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config) {
"invalid state");
sdup->config = config;
usbStart(config->usbp, &config->usb_config);
- config->usbp->usb_param = sdup;
+ config->usbp->param = sdup;
sdup->state = SDU_READY;
chSysUnlock();
}
@@ -242,11 +244,16 @@ void sduStop(SerialUSBDriver *sdup) {
* - CDC_SET_LINE_CODING.
* - CDC_SET_CONTROL_LINE_STATE.
* .
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @return The hook status.
+ * @retval TRUE Message handled internally.
+ * @retval FALSE Message not handled.
*/
bool_t sduRequestsHook(USBDriver *usbp) {
- if ((usbp->usb_setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
- switch (usbp->usb_setup[1]) {
+ if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
+ switch (usbp->setup[1]) {
case CDC_GET_LINE_CODING:
usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
return TRUE;
@@ -265,36 +272,44 @@ bool_t sduRequestsHook(USBDriver *usbp) {
}
/**
- * @brief Default data request callback.
+ * @brief Default data transmitted callback.
* @details The application must use this function as callback for the IN
* data endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
*/
-void sduDataRequest(USBDriver *usbp, usbep_t ep) {
- SerialUSBDriver *sdup = usbp->usb_param;
- size_t n;
+void sduDataTransmitted(USBDriver *usbp, usbep_t ep) {
+ SerialUSBDriver *sdup = usbp->param;
+ size_t n, w;
chSysLockFromIsr();
/* If there is any data in the output queue then it is sent within a
single packet and the queue is emptied.*/
n = chOQGetFullI(&sdup->oqueue);
if (n > 0) {
- n = usbWriteI(usbp, ep, sdup->oqueue.q_buffer, n);
- if (n > 0) {
- sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
- chSemSetCounterI(&sdup->oqueue.q_sem, SERIAL_USB_BUFFERS_SIZE);
+ w = usbWritePacketI(usbp, ep, sdup->oqueue.q_buffer, n);
+ if (w != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
+ sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
+ sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue);
+ while (notempty(&sdup->oqueue.q_waiting))
+ chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
chSysUnlockFromIsr();
}
/**
- * @brief Default data available callback.
+ * @brief Default data received callback.
* @details The application must use this function as callback for the OUT
* data endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
*/
-void sduDataAvailable(USBDriver *usbp, usbep_t ep) {
- SerialUSBDriver *sdup = usbp->usb_param;
+void sduDataReceived(USBDriver *usbp, usbep_t ep) {
+ SerialUSBDriver *sdup = usbp->param;
chSysLockFromIsr();
/* Writes to the input queue can only happen when the queue has been
@@ -302,11 +317,14 @@ void sduDataAvailable(USBDriver *usbp, usbep_t ep) {
if (chIQIsEmptyI(&sdup->iqueue)) {
size_t n;
- n = usbReadI(usbp, ep, sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
- if (n > 0) {
- sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
- chSemSetCounterI(&sdup->iqueue.q_sem, n);
+ n = usbReadPacketI(usbp, ep, sdup->iqueue.q_buffer,
+ SERIAL_USB_BUFFERS_SIZE);
+ if (n != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
+ sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
+ sdup->iqueue.q_counter = n;
+ while (notempty(&sdup->iqueue.q_waiting))
+ chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
chSysUnlockFromIsr();
@@ -316,8 +334,11 @@ void sduDataAvailable(USBDriver *usbp, usbep_t ep) {
* @brief Default data received callback.
* @details The application must use this function as callback for the IN
* interrupt endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
*/
-void sduInterruptRequest(USBDriver *usbp, usbep_t ep) {
+void sduInterruptTransmitted(USBDriver *usbp, usbep_t ep) {
(void)usbp;
(void)ep;
diff --git a/os/hal/src/spi.c b/os/hal/src/spi.c
index e99126b9e..aaf0115eb 100644
--- a/os/hal/src/spi.c
+++ b/os/hal/src/spi.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,16 +68,16 @@ void spiInit(void) {
*/
void spiObjectInit(SPIDriver *spip) {
- spip->spd_state = SPI_STOP;
- spip->spd_config = NULL;
+ spip->state = SPI_STOP;
+ spip->config = NULL;
#if SPI_USE_WAIT
- spip->spd_thread = NULL;
+ spip->thread = NULL;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION
#if CH_USE_MUTEXES
- chMtxInit(&spip->spd_mutex);
+ chMtxInit(&spip->mutex);
#else
- chSemInit(&spip->spd_semaphore, 1);
+ chSemInit(&spip->semaphore, 1);
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_INIT_HOOK)
@@ -97,11 +98,11 @@ void spiStart(SPIDriver *spip, const SPIConfig *config) {
chDbgCheck((spip != NULL) && (config != NULL), "spiStart");
chSysLock();
- chDbgAssert((spip->spd_state == SPI_STOP) || (spip->spd_state == SPI_READY),
+ chDbgAssert((spip->state == SPI_STOP) || (spip->state == SPI_READY),
"spiStart(), #1", "invalid state");
- spip->spd_config = config;
+ spip->config = config;
spi_lld_start(spip);
- spip->spd_state = SPI_READY;
+ spip->state = SPI_READY;
chSysUnlock();
}
@@ -119,11 +120,11 @@ void spiStop(SPIDriver *spip) {
chDbgCheck(spip != NULL, "spiStop");
chSysLock();
- chDbgAssert((spip->spd_state == SPI_STOP) || (spip->spd_state == SPI_READY),
+ chDbgAssert((spip->state == SPI_STOP) || (spip->state == SPI_READY),
"spiStop(), #1", "invalid state");
spi_lld_unselect(spip);
spi_lld_stop(spip);
- spip->spd_state = SPI_STOP;
+ spip->state = SPI_STOP;
chSysUnlock();
}
@@ -139,8 +140,7 @@ void spiSelect(SPIDriver *spip) {
chDbgCheck(spip != NULL, "spiSelect");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiSelect(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiSelect(), #1", "not ready");
spiSelectI(spip);
chSysUnlock();
}
@@ -158,8 +158,7 @@ void spiUnselect(SPIDriver *spip) {
chDbgCheck(spip != NULL, "spiUnselect");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiUnselect(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiUnselect(), #1", "not ready");
spiUnselectI(spip);
chSysUnlock();
}
@@ -182,8 +181,7 @@ void spiStartIgnore(SPIDriver *spip, size_t n) {
chDbgCheck((spip != NULL) && (n > 0), "spiStartIgnore");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiStartIgnore(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiStartIgnore(), #1", "not ready");
spiStartIgnoreI(spip, n);
chSysUnlock();
}
@@ -212,8 +210,7 @@ void spiStartExchange(SPIDriver *spip, size_t n,
"spiStartExchange");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiStartExchange(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiStartExchange(), #1", "not ready");
spiStartExchangeI(spip, n, txbuf, rxbuf);
chSysUnlock();
}
@@ -239,8 +236,7 @@ void spiStartSend(SPIDriver *spip, size_t n, const void *txbuf) {
"spiStartSend");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiStartSend(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiStartSend(), #1", "not ready");
spiStartSendI(spip, n, txbuf);
chSysUnlock();
}
@@ -266,8 +262,7 @@ void spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf) {
"spiStartReceive");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiStartReceive(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiStartReceive(), #1", "not ready");
spiStartReceiveI(spip, n, rxbuf);
chSysUnlock();
}
@@ -280,7 +275,7 @@ void spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf) {
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
- * without callbacks (@p spc_endcb = @p NULL).
+ * without callbacks (@p end_cb = @p NULL).
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be ignored
@@ -292,10 +287,8 @@ void spiIgnore(SPIDriver *spip, size_t n) {
chDbgCheck((spip != NULL) && (n > 0), "spiIgnoreWait");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiIgnore(), #1", "not ready");
- chDbgAssert(spip->spd_config->spc_endcb == NULL,
- "spiIgnore(), #2", "has callback");
+ chDbgAssert(spip->state == SPI_READY, "spiIgnore(), #1", "not ready");
+ chDbgAssert(spip->config->end_cb == NULL, "spiIgnore(), #2", "has callback");
spiStartIgnoreI(spip, n);
_spi_wait_s(spip);
chSysUnlock();
@@ -308,7 +301,7 @@ void spiIgnore(SPIDriver *spip, size_t n) {
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
- * without callbacks (@p spc_endcb = @p NULL).
+ * without callbacks (@p end_cb = @p NULL).
* @note The buffers are organized as uint8_t arrays for data sizes below
* or equal to 8 bits else it is organized as uint16_t arrays.
*
@@ -326,9 +319,8 @@ void spiExchange(SPIDriver *spip, size_t n,
"spiExchange");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiExchange(), #1", "not ready");
- chDbgAssert(spip->spd_config->spc_endcb == NULL,
+ chDbgAssert(spip->state == SPI_READY, "spiExchange(), #1", "not ready");
+ chDbgAssert(spip->config->end_cb == NULL,
"spiExchange(), #2", "has callback");
spiStartExchangeI(spip, n, txbuf, rxbuf);
_spi_wait_s(spip);
@@ -341,7 +333,7 @@ void spiExchange(SPIDriver *spip, size_t n,
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
- * without callbacks (@p spc_endcb = @p NULL).
+ * without callbacks (@p end_cb = @p NULL).
* @note The buffers are organized as uint8_t arrays for data sizes below
* or equal to 8 bits else it is organized as uint16_t arrays.
*
@@ -353,14 +345,11 @@ void spiExchange(SPIDriver *spip, size_t n,
*/
void spiSend(SPIDriver *spip, size_t n, const void *txbuf) {
- chDbgCheck((spip != NULL) && (n > 0) && (txbuf != NULL),
- "spiSend");
+ chDbgCheck((spip != NULL) && (n > 0) && (txbuf != NULL), "spiSend");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiSend(), #1", "not ready");
- chDbgAssert(spip->spd_config->spc_endcb == NULL,
- "spiSend(), #2", "has callback");
+ chDbgAssert(spip->state == SPI_READY, "spiSend(), #1", "not ready");
+ chDbgAssert(spip->config->end_cb == NULL, "spiSend(), #2", "has callback");
spiStartSendI(spip, n, txbuf);
_spi_wait_s(spip);
chSysUnlock();
@@ -372,7 +361,7 @@ void spiSend(SPIDriver *spip, size_t n, const void *txbuf) {
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
- * without callbacks (@p spc_endcb = @p NULL).
+ * without callbacks (@p end_cb = @p NULL).
* @note The buffers are organized as uint8_t arrays for data sizes below
* or equal to 8 bits else it is organized as uint16_t arrays.
*
@@ -388,9 +377,8 @@ void spiReceive(SPIDriver *spip, size_t n, void *rxbuf) {
"spiReceive");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiReceive(), #1", "not ready");
- chDbgAssert(spip->spd_config->spc_endcb == NULL,
+ chDbgAssert(spip->state == SPI_READY, "spiReceive(), #1", "not ready");
+ chDbgAssert(spip->config->end_cb == NULL,
"spiReceive(), #2", "has callback");
spiStartReceiveI(spip, n, rxbuf);
_spi_wait_s(spip);
@@ -415,9 +403,9 @@ void spiAcquireBus(SPIDriver *spip) {
chDbgCheck(spip != NULL, "spiAcquireBus");
#if CH_USE_MUTEXES
- chMtxLock(&spip->spd_mutex);
+ chMtxLock(&spip->mutex);
#elif CH_USE_SEMAPHORES
- chSemWait(&spip->spd_semaphore);
+ chSemWait(&spip->semaphore);
#endif
}
@@ -438,7 +426,7 @@ void spiReleaseBus(SPIDriver *spip) {
(void)spip;
chMtxUnlock();
#elif CH_USE_SEMAPHORES
- chSemSignal(&spip->spd_semaphore);
+ chSemSignal(&spip->semaphore);
#endif
}
#endif /* SPI_USE_MUTUAL_EXCLUSION */
diff --git a/os/hal/src/uart.c b/os/hal/src/uart.c
index 4a21e907f..05fdbb168 100644
--- a/os/hal/src/uart.c
+++ b/os/hal/src/uart.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,10 +68,10 @@ void uartInit(void) {
*/
void uartObjectInit(UARTDriver *uartp) {
- uartp->ud_state = UART_STOP;
- uartp->ud_txstate = UART_TX_IDLE;
- uartp->ud_rxstate = UART_RX_IDLE;
- uartp->ud_config = NULL;
+ uartp->state = UART_STOP;
+ uartp->txstate = UART_TX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
+ uartp->config = NULL;
/* Optional, user-defined initializer.*/
#if defined(UART_DRIVER_EXT_INIT_HOOK)
UART_DRIVER_EXT_INIT_HOOK(uartp);
@@ -90,14 +91,12 @@ void uartStart(UARTDriver *uartp, const UARTConfig *config) {
chDbgCheck((uartp != NULL) && (config != NULL), "uartStart");
chSysLock();
- chDbgAssert((uartp->ud_state == UART_STOP) ||
- (uartp->ud_state == UART_READY),
- "uartStart(), #1",
- "invalid state");
+ chDbgAssert((uartp->state == UART_STOP) || (uartp->state == UART_READY),
+ "uartStart(), #1", "invalid state");
- uartp->ud_config = config;
+ uartp->config = config;
uart_lld_start(uartp);
- uartp->ud_state = UART_READY;
+ uartp->state = UART_READY;
chSysUnlock();
}
@@ -113,15 +112,13 @@ void uartStop(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStop");
chSysLock();
- chDbgAssert((uartp->ud_state == UART_STOP) ||
- (uartp->ud_state == UART_READY),
- "uartStop(), #1",
- "invalid state");
+ chDbgAssert((uartp->state == UART_STOP) || (uartp->state == UART_READY),
+ "uartStop(), #1", "invalid state");
uart_lld_stop(uartp);
- uartp->ud_state = UART_STOP;
- uartp->ud_txstate = UART_TX_IDLE;
- uartp->ud_rxstate = UART_RX_IDLE;
+ uartp->state = UART_STOP;
+ uartp->txstate = UART_TX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
chSysUnlock();
}
@@ -142,13 +139,11 @@ void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf) {
"uartStartSend");
chSysLock();
- chDbgAssert((uartp->ud_state == UART_READY) &&
- (uartp->ud_txstate == UART_TX_IDLE),
- "uartStartSend(), #1",
- "not active");
+ chDbgAssert((uartp->state == UART_READY) && (uartp->txstate == UART_TX_IDLE),
+ "uartStartSend(), #1", "not active");
uart_lld_start_send(uartp, n, txbuf);
- uartp->ud_txstate = UART_TX_ACTIVE;
+ uartp->txstate = UART_TX_ACTIVE;
chSysUnlock();
}
@@ -169,12 +164,11 @@ void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf) {
chDbgCheck((uartp != NULL) && (n > 0) && (txbuf != NULL),
"uartStartSendI");
- chDbgAssert((uartp->ud_state == UART_READY) &&
- (uartp->ud_txstate != UART_TX_ACTIVE),
- "uartStartSendI(), #1",
- "not active");
+ chDbgAssert((uartp->state == UART_READY) &&
+ (uartp->txstate != UART_TX_ACTIVE),
+ "uartStartSendI(), #1", "not active");
uart_lld_start_send(uartp, n, txbuf);
- uartp->ud_txstate = UART_TX_ACTIVE;
+ uartp->txstate = UART_TX_ACTIVE;
}
/**
@@ -195,13 +189,11 @@ size_t uartStopSend(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStopSend");
chSysLock();
- chDbgAssert(uartp->ud_state == UART_READY,
- "uartStopSend(), #1",
- "not active");
+ chDbgAssert(uartp->state == UART_READY, "uartStopSend(), #1", "not active");
- if (uartp->ud_txstate == UART_TX_ACTIVE) {
+ if (uartp->txstate == UART_TX_ACTIVE) {
n = uart_lld_stop_send(uartp);
- uartp->ud_txstate = UART_TX_IDLE;
+ uartp->txstate = UART_TX_IDLE;
}
else
n = 0;
@@ -226,13 +218,11 @@ size_t uartStopSendI(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStopSendI");
- chDbgAssert(uartp->ud_state == UART_READY,
- "uartStopSendI(), #1",
- "not active");
+ chDbgAssert(uartp->state == UART_READY, "uartStopSendI(), #1", "not active");
- if (uartp->ud_txstate == UART_TX_ACTIVE) {
+ if (uartp->txstate == UART_TX_ACTIVE) {
size_t n = uart_lld_stop_send(uartp);
- uartp->ud_txstate = UART_TX_IDLE;
+ uartp->txstate = UART_TX_IDLE;
return n;
}
return 0;
@@ -255,13 +245,11 @@ void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf) {
"uartStartReceive");
chSysLock();
- chDbgAssert((uartp->ud_state == UART_READY) &&
- (uartp->ud_rxstate == UART_RX_IDLE),
- "uartStartReceive(), #1",
- "not active");
+ chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE),
+ "uartStartReceive(), #1", "not active");
uart_lld_start_receive(uartp, n, rxbuf);
- uartp->ud_rxstate = UART_RX_ACTIVE;
+ uartp->rxstate = UART_RX_ACTIVE;
chSysUnlock();
}
@@ -282,13 +270,11 @@ void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf) {
chDbgCheck((uartp != NULL) && (n > 0) && (rxbuf != NULL),
"uartStartReceiveI");
- chDbgAssert((uartp->ud_state == UART_READY) &&
- (uartp->ud_rxstate == UART_RX_IDLE),
- "uartStartReceiveI(), #1",
- "not active");
+ chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE),
+ "uartStartReceiveI(), #1", "not active");
uart_lld_start_receive(uartp, n, rxbuf);
- uartp->ud_rxstate = UART_RX_ACTIVE;
+ uartp->rxstate = UART_RX_ACTIVE;
}
/**
@@ -309,13 +295,12 @@ size_t uartStopReceive(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStopReceive");
chSysLock();
- chDbgAssert(uartp->ud_state == UART_READY,
- "uartStopReceive(), #1",
- "not active");
+ chDbgAssert(uartp->state == UART_READY,
+ "uartStopReceive(), #1", "not active");
- if (uartp->ud_rxstate == UART_RX_ACTIVE) {
+ if (uartp->rxstate == UART_RX_ACTIVE) {
n = uart_lld_stop_receive(uartp);
- uartp->ud_rxstate = UART_RX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
}
else
n = 0;
@@ -339,13 +324,12 @@ size_t uartStopReceive(UARTDriver *uartp) {
size_t uartStopReceiveI(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStopReceiveI");
- chDbgAssert(uartp->ud_state == UART_READY,
- "uartStopReceiveI(), #1",
- "not active");
+ chDbgAssert(uartp->state == UART_READY,
+ "uartStopReceiveI(), #1", "not active");
- if (uartp->ud_rxstate == UART_RX_ACTIVE) {
+ if (uartp->rxstate == UART_RX_ACTIVE) {
size_t n = uart_lld_stop_receive(uartp);
- uartp->ud_rxstate = UART_RX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
return n;
}
return 0;
diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c
index 3cc076443..484590f3b 100644
--- a/os/hal/src/usb.c
+++ b/os/hal/src/usb.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -54,74 +55,19 @@ static const uint8_t halted_status[] = {0x01, 0x00};
*
* @param[in] usbp pointer to the @p USBDriver object
*/
-void set_address(USBDriver *usbp) {
+static void set_address(USBDriver *usbp) {
- usbp->usb_address = usbp->usb_setup[2];
- usb_lld_set_address(usbp, usbp->usb_address);
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_ADDRESS);
- usbp->usb_state = USB_SELECTED;
-}
-
-/**
- * @brief Starts a receive phase on the endpoint zero.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- */
-static void start_rx_ep0(USBDriver *usbp) {
-
- if (usbp->usb_ep0n > 0) {
- /* The received data cannot exceed the available amount.*/
- if (usbp->usb_ep0n > usbp->usb_ep0max)
- usbp->usb_ep0n = usbp->usb_ep0max;
-
- /* Determines the maximum amount that can be received using a
- single packet.*/
- if (usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_out_maxsize)
- usbp->usb_ep0lastsize = usbp->usb_ep[0]->uep_config->uepc_out_maxsize;
- else
- usbp->usb_ep0lastsize = usbp->usb_ep0n;
- usbp->usb_ep0state = USB_EP0_RX;
- }
- else {
- /* Sending zero sized status packet.*/
- usb_lld_write(usbp, 0, NULL, 0);
- usbp->usb_ep0state = USB_EP0_SENDING_STS;
- }
-}
-
-/**
- * @brief Starts a transmission phase on the endpoint zero.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- */
-static void start_tx_ep0(USBDriver *usbp) {
-
- if (usbp->usb_ep0n > 0) {
- /* The transmitted data cannot exceed the requested amount.*/
- if (usbp->usb_ep0n > usbp->usb_ep0max)
- usbp->usb_ep0n = usbp->usb_ep0max;
-
- /* Determines the maximum amount that can be transmitted using a
- single packet.*/
- if (usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_in_maxsize)
- usbp->usb_ep0lastsize = usbp->usb_ep[0]->uep_config->uepc_in_maxsize;
- else
- usbp->usb_ep0lastsize = usbp->usb_ep0n;
-
- /* Starts transmission.*/
- usb_lld_write(usbp, 0, usbp->usb_ep0next, usbp->usb_ep0lastsize);
- usbp->usb_ep0state = USB_EP0_TX;
- }
- else
- usbp->usb_ep0state = USB_EP0_WAITING_STS;
+ usbp->address = usbp->setup[2];
+ usb_lld_set_address(usbp);
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_ADDRESS);
+ usbp->state = USB_SELECTED;
}
/**
* @brief Standard requests handler.
* @details This is the standard requests default handler, most standard
* requests are handled here, the user can override the standard
- * handling using the @p uc_requests_hook_cb hook in the
+ * handling using the @p requests_hook_cb hook in the
* @p USBConfig structure.
*
* @param[in] usbp pointer to the @p USBDriver object
@@ -133,18 +79,18 @@ static bool_t default_handler(USBDriver *usbp) {
const USBDescriptor *dp;
/* Decoding the request.*/
- switch (((usbp->usb_setup[0] & (USB_RTYPE_RECIPIENT_MASK |
- USB_RTYPE_TYPE_MASK)) |
- (usbp->usb_setup[1] << 8))) {
+ switch (((usbp->setup[0] & (USB_RTYPE_RECIPIENT_MASK |
+ USB_RTYPE_TYPE_MASK)) |
+ (usbp->setup[1] << 8))) {
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_GET_STATUS << 8):
/* Just returns the current status word.*/
- usbSetupTransfer(usbp, (uint8_t *)&usbp->usb_status, 2, NULL);
+ usbSetupTransfer(usbp, (uint8_t *)&usbp->status, 2, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_CLEAR_FEATURE << 8):
/* Only the DEVICE_REMOTE_WAKEUP is handled here, any other feature
number is handled as an error.*/
- if (usbp->usb_setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) {
- usbp->usb_status &= ~2;
+ if (usbp->setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) {
+ usbp->status &= ~2;
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
}
@@ -152,39 +98,46 @@ static bool_t default_handler(USBDriver *usbp) {
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_SET_FEATURE << 8):
/* Only the DEVICE_REMOTE_WAKEUP is handled here, any other feature
number is handled as an error.*/
- if (usbp->usb_setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) {
- usbp->usb_status |= 2;
+ if (usbp->setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) {
+ usbp->status |= 2;
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
}
return FALSE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_SET_ADDRESS << 8):
- /* The handling is posponed to after the status phase in order to allow
- the proper completion of the transaction.*/
+ /* The SET_ADDRESS handling can be performed here or postponed after
+ the status packed depending on the USB_SET_ADDRESS_MODE low
+ driver setting.*/
+#if USB_SET_ADDRESS_MODE == USB_EARLY_SET_ADDRESS
+ if ((usbp->setup[0] == USB_RTYPE_RECIPIENT_DEVICE) &&
+ (usbp->setup[1] == USB_REQ_SET_ADDRESS))
+ set_address(usbp);
+ usbSetupTransfer(usbp, NULL, 0, NULL);
+#else
usbSetupTransfer(usbp, NULL, 0, set_address);
+#endif
return TRUE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_GET_DESCRIPTOR << 8):
/* Handling descriptor requests from the host.*/
- dp = usbp->usb_config->uc_get_descriptor_cb(
- usbp, usbp->usb_setup[3], usbp->usb_setup[2],
- usb_lld_fetch_word(&usbp->usb_setup[4]));
+ dp = usbp->config->get_descriptor_cb(
+ usbp, usbp->setup[3], usbp->setup[2],
+ usb_lld_fetch_word(&usbp->setup[4]));
if (dp == NULL)
return FALSE;
usbSetupTransfer(usbp, (uint8_t *)dp->ud_string, dp->ud_size, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_GET_CONFIGURATION << 8):
/* Returning the last selected configuration.*/
- usbSetupTransfer(usbp, &usbp->usb_configuration, 1, NULL);
+ usbSetupTransfer(usbp, &usbp->configuration, 1, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_SET_CONFIGURATION << 8):
/* Handling configuration selection from the host.*/
- usbp->usb_configuration = usbp->usb_setup[2];
- if (usbp->usb_configuration == 0)
- usbp->usb_state = USB_SELECTED;
+ usbp->configuration = usbp->setup[2];
+ if (usbp->configuration == 0)
+ usbp->state = USB_SELECTED;
else
- usbp->usb_state = USB_ACTIVE;
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_CONFIGURED);
+ usbp->state = USB_ACTIVE;
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_CONFIGURED);
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_INTERFACE | (USB_REQ_GET_STATUS << 8):
@@ -195,8 +148,8 @@ static bool_t default_handler(USBDriver *usbp) {
return TRUE;
case USB_RTYPE_RECIPIENT_ENDPOINT | (USB_REQ_GET_STATUS << 8):
/* Sending the EP status.*/
- if (usbp->usb_setup[4] & 0x80) {
- switch (usb_lld_get_status_in(usbp, usbp->usb_setup[4] & 0x0F)) {
+ if (usbp->setup[4] & 0x80) {
+ switch (usb_lld_get_status_in(usbp, usbp->setup[4] & 0x0F)) {
case EP_STATUS_STALLED:
usbSetupTransfer(usbp, (uint8_t *)halted_status, 2, NULL);
return TRUE;
@@ -208,7 +161,7 @@ static bool_t default_handler(USBDriver *usbp) {
}
}
else {
- switch (usb_lld_get_status_out(usbp, usbp->usb_setup[4] & 0x0F)) {
+ switch (usb_lld_get_status_out(usbp, usbp->setup[4] & 0x0F)) {
case EP_STATUS_STALLED:
usbSetupTransfer(usbp, (uint8_t *)halted_status, 2, NULL);
return TRUE;
@@ -221,27 +174,27 @@ static bool_t default_handler(USBDriver *usbp) {
}
case USB_RTYPE_RECIPIENT_ENDPOINT | (USB_REQ_CLEAR_FEATURE << 8):
/* Only ENDPOINT_HALT is handled as feature.*/
- if (usbp->usb_setup[2] != USB_FEATURE_ENDPOINT_HALT)
+ if (usbp->setup[2] != USB_FEATURE_ENDPOINT_HALT)
return FALSE;
/* Clearing the EP status, not valid for EP0, it is ignored in that case.*/
- if ((usbp->usb_setup[4] & 0x0F) > 0) {
- if (usbp->usb_setup[4] & 0x80)
- usb_lld_clear_in(usbp, usbp->usb_setup[4] & 0x0F);
+ if ((usbp->setup[4] & 0x0F) > 0) {
+ if (usbp->setup[4] & 0x80)
+ usb_lld_clear_in(usbp, usbp->setup[4] & 0x0F);
else
- usb_lld_clear_out(usbp, usbp->usb_setup[4] & 0x0F);
+ usb_lld_clear_out(usbp, usbp->setup[4] & 0x0F);
}
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_ENDPOINT | (USB_REQ_SET_FEATURE << 8):
/* Only ENDPOINT_HALT is handled as feature.*/
- if (usbp->usb_setup[2] != USB_FEATURE_ENDPOINT_HALT)
+ if (usbp->setup[2] != USB_FEATURE_ENDPOINT_HALT)
return FALSE;
/* Stalling the EP, not valid for EP0, it is ignored in that case.*/
- if ((usbp->usb_setup[4] & 0x0F) > 0) {
- if (usbp->usb_setup[4] & 0x80)
- usb_lld_stall_in(usbp, usbp->usb_setup[4] & 0x0F);
+ if ((usbp->setup[4] & 0x0F) > 0) {
+ if (usbp->setup[4] & 0x80)
+ usb_lld_stall_in(usbp, usbp->setup[4] & 0x0F);
else
- usb_lld_stall_out(usbp, usbp->usb_setup[4] & 0x0F);
+ usb_lld_stall_out(usbp, usbp->setup[4] & 0x0F);
}
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
@@ -282,9 +235,11 @@ void usbInit(void) {
*/
void usbObjectInit(USBDriver *usbp) {
- usbp->usb_state = USB_STOP;
- usbp->usb_config = NULL;
- usbp->usb_param = NULL;
+ usbp->state = USB_STOP;
+ usbp->config = NULL;
+ usbp->param = NULL;
+ usbp->transmitting = 0;
+ usbp->receiving = 0;
}
/**
@@ -301,13 +256,13 @@ void usbStart(USBDriver *usbp, const USBConfig *config) {
chDbgCheck((usbp != NULL) && (config != NULL), "usbStart");
chSysLock();
- chDbgAssert((usbp->usb_state == USB_STOP) || (usbp->usb_state == USB_READY),
+ chDbgAssert((usbp->state == USB_STOP) || (usbp->state == USB_READY),
"usbStart(), #1", "invalid state");
- usbp->usb_config = config;
+ usbp->config = config;
for (i = 0; i <= USB_MAX_ENDPOINTS; i++)
- usbp->usb_ep[i] = NULL;
+ usbp->epc[i] = NULL;
usb_lld_start(usbp);
- usbp->usb_state = USB_READY;
+ usbp->state = USB_READY;
chSysUnlock();
}
@@ -323,11 +278,10 @@ void usbStop(USBDriver *usbp) {
chDbgCheck(usbp != NULL, "usbStop");
chSysLock();
- chDbgAssert((usbp->usb_state == USB_STOP) || (usbp->usb_state == USB_READY),
- "usbStop(), #1",
- "invalid state");
+ chDbgAssert((usbp->state == USB_STOP) || (usbp->state == USB_READY),
+ "usbStop(), #1", "invalid state");
usb_lld_stop(usbp);
- usbp->usb_state = USB_STOP;
+ usbp->state = USB_STOP;
chSysUnlock();
}
@@ -340,23 +294,24 @@ void usbStop(USBDriver *usbp) {
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @param[out] epp pointer to an endpoint state descriptor structure
* @param[in] epcp the endpoint configuration
*
* @iclass
*/
-void usbInitEndpointI(USBDriver *usbp, usbep_t ep, USBEndpointState *epp,
+void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
const USBEndpointConfig *epcp) {
- chDbgAssert(usbp->usb_state == USB_ACTIVE,
+ chDbgAssert(usbp->state == USB_ACTIVE,
"usbEnableEndpointI(), #1", "invalid state");
- chDbgAssert(usbp->usb_ep[ep] != NULL,
+ chDbgAssert(usbp->epc[ep] != NULL,
"usbEnableEndpointI(), #2", "already initialized");
/* Logically enabling the endpoint in the USBDriver structure.*/
- memset(epp, 0, sizeof(USBEndpointState));
- epp->uep_config = epcp;
- usbp->usb_ep[ep] = epp;
+ if (!(epcp->ep_mode & USB_EP_MODE_PACKET)) {
+ memset(epcp->in_state, 0, sizeof(USBInEndpointState));
+ memset(epcp->out_state, 0, sizeof(USBOutEndpointState));
+ }
+ usbp->epc[ep] = epcp;
/* Low level endpoint activation.*/
usb_lld_init_endpoint(usbp, ep);
@@ -376,18 +331,174 @@ void usbInitEndpointI(USBDriver *usbp, usbep_t ep, USBEndpointState *epp,
void usbDisableEndpointsI(USBDriver *usbp) {
unsigned i;
- chDbgAssert(usbp->usb_state == USB_SELECTED,
+ chDbgAssert(usbp->state == USB_SELECTED,
"usbDisableEndpointsI(), #1", "invalid state");
+ usbp->transmitting &= ~1;
+ usbp->receiving &= ~1;
for (i = 1; i <= USB_MAX_ENDPOINTS; i++)
- usbp->usb_ep[i] = NULL;
+ usbp->epc[i] = NULL;
/* Low level endpoints deactivation.*/
usb_lld_disable_endpoints(usbp);
}
/**
+ * @brief Reads a packet from the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @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
+ * @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 USB_ENDPOINT_BUSY Endpoint busy receiving.
+ * @retval 0 Zero size packet received.
+ *
+ * @iclass
+ */
+size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+
+ if (usbGetReceiveStatusI(usbp, ep))
+ return USB_ENDPOINT_BUSY;
+
+ usbp->receiving |= (1 << ep);
+ return usb_lld_read_packet(usbp, ep, buf, n);;
+}
+
+/**
+ * @brief Writes a packet to the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to transmit the packet.
+ *
+ * @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.
+ * @return The operation status.
+ * @retval USB_ENDPOINT_BUSY Endpoint busy transmitting.
+ * @retval 0 Operation complete.
+ *
+ * @iclass
+ */
+size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+
+ if (usbGetTransmitStatusI(usbp, ep))
+ return USB_ENDPOINT_BUSY;
+
+ usbp->transmitting |= (1 << ep);
+ usb_lld_write_packet(usbp, ep, buf, n);
+ return 0;
+}
+
+/**
+ * @brief Starts a receive transaction on an OUT endpoint.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in transaction mode.
+ * @post The endpoint callback is invoked when the transfer has been
+ * completed.
+ *
+ * @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
+ * @return The operation status.
+ * @retval FALSE Operation started successfully.
+ * @retval TRUE Endpoint busy, operation not started.
+ *
+ * @iclass
+ */
+bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+
+ if (usbGetReceiveStatusI(usbp, ep))
+ return TRUE;
+
+ usbp->receiving |= (1 << ep);
+ usb_lld_start_out(usbp, ep, buf, n);
+ return FALSE;
+}
+
+/**
+ * @brief Starts a transmit transaction on an IN endpoint.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in transaction mode.
+ * @post The endpoint callback is invoked when the transfer has been
+ * completed.
+ *
+ * @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
+ * @return The operation status.
+ * @retval FALSE Operation started successfully.
+ * @retval TRUE Endpoint busy, operation not started.
+ *
+ * @iclass
+ */
+bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+
+ if (usbGetTransmitStatusI(usbp, ep))
+ return TRUE;
+
+ usbp->transmitting |= (1 << ep);
+ usb_lld_start_in(usbp, ep, buf, n);
+ return FALSE;
+}
+
+/**
+ * @brief Stalls an OUT endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The operation status.
+ * @retval FALSE Endpoint stalled.
+ * @retval TRUE Endpoint busy, not stalled.
+ *
+ * @iclass
+ */
+bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) {
+
+ if (usbGetReceiveStatusI(usbp, ep))
+ return TRUE;
+
+ usb_lld_stall_out(usbp, ep);
+ return FALSE;
+}
+
+/**
+ * @brief Stalls an IN endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The operation status.
+ * @retval FALSE Endpoint stalled.
+ * @retval TRUE Endpoint busy, not stalled.
+ *
+ * @iclass
+ */
+bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep) {
+
+ if (usbGetTransmitStatusI(usbp, ep))
+ return TRUE;
+
+ usb_lld_stall_in(usbp, ep);
+ return FALSE;
+}
+
+/**
* @brief USB reset routine.
+ * @details This function must be invoked when an USB bus reset condition is
+ * detected.
*
* @param[in] usbp pointer to the @p USBDriver object
*
@@ -396,24 +507,93 @@ void usbDisableEndpointsI(USBDriver *usbp) {
void _usb_reset(USBDriver *usbp) {
unsigned i;
- usbp->usb_state = USB_READY;
- usbp->usb_status = 0;
- usbp->usb_address = 0;
- usbp->usb_configuration = 0;
+ usbp->state = USB_READY;
+ usbp->status = 0;
+ usbp->address = 0;
+ usbp->configuration = 0;
+ usbp->transmitting = 0;
+ usbp->receiving = 0;
/* Invalidates all endpoints into the USBDriver structure.*/
for (i = 0; i <= USB_MAX_ENDPOINTS; i++)
- usbp->usb_ep[i] = NULL;
+ usbp->epc[i] = NULL;
/* EP0 state machine initialization.*/
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ usbp->ep0state = USB_EP0_WAITING_SETUP;
/* Low level reset.*/
usb_lld_reset(usbp);
+}
- /* Endpoint zero initialization.*/
-/* usbp->usb_ep[0].uep_config = &usb_lld_ep0config;
- usb_lld_init_endpoint(usbp, 0, &usb_lld_ep0config);*/
+/**
+ * @brief Default EP0 SETUP callback.
+ * @details This function is used by the low level driver as default handler
+ * for EP0 SETUP events.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number, always zero
+ *
+ * @notapi
+ */
+void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
+ size_t max;
+
+ usbp->ep0state = USB_EP0_WAITING_SETUP;
+ usbReadSetup(usbp, ep, usbp->setup);
+
+ /* First verify if the application has an handler installed for this
+ request.*/
+ if (!(usbp->config->requests_hook_cb) ||
+ !(usbp->config->requests_hook_cb(usbp))) {
+ /* Invoking the default handler, if this fails then stalls the
+ endpoint zero as error.*/
+ if (((usbp->setup[0] & USB_RTYPE_TYPE_MASK) != USB_RTYPE_TYPE_STD) ||
+ !default_handler(usbp)) {
+ /* Error response, the state machine goes into an error state, the low
+ level layer will have to reset it to USB_EP0_WAITING_SETUP after
+ receiving a SETUP packet.*/
+ usb_lld_stall_in(usbp, 0);
+ usb_lld_stall_out(usbp, 0);
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED);
+ usbp->ep0state = USB_EP0_ERROR;
+ }
+ }
+
+ /* Transfer preparation. The request handler must have populated
+ correctly the fields ep0next, ep0n and ep0endcb using the macro
+ usbSetupTransfer().*/
+ max = usb_lld_fetch_word(&usbp->setup[6]);
+ /* The transfer size cannot exceed the specified amount.*/
+ if (usbp->ep0n > max)
+ usbp->ep0n = max;
+ if ((usbp->setup[0] & USB_RTYPE_DIR_MASK) == USB_RTYPE_DIR_DEV2HOST) {
+ /* IN phase.*/
+ if (usbp->ep0n > 0) {
+ /* Starts the transmit phase.*/
+ usbp->ep0state = USB_EP0_TX;
+ usb_lld_start_in(usbp, 0, usbp->ep0next, usbp->ep0n);
+ }
+ else {
+ /* No transmission phase, directly receiving the zero sized status
+ packet.*/
+ usbp->ep0state = USB_EP0_WAITING_STS;
+ usb_lld_start_out(usbp, 0, NULL, 0);
+ }
+ }
+ else {
+ /* OUT phase.*/
+ if (usbp->ep0n > 0) {
+ /* Starts the receive phase.*/
+ usbp->ep0state = USB_EP0_RX;
+ usb_lld_start_out(usbp, 0, usbp->ep0next, usbp->ep0n);
+ }
+ else {
+ /* No receive phase, directly sending the zero sized status
+ packet.*/
+ usbp->ep0state = USB_EP0_SENDING_STS;
+ usb_lld_start_in(usbp, 0, NULL, 0);
+ }
+ }
}
/**
@@ -427,43 +607,41 @@ void _usb_reset(USBDriver *usbp) {
* @notapi
*/
void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
+ size_t max;
(void)ep;
- switch (usbp->usb_ep0state) {
+ switch (usbp->ep0state) {
case USB_EP0_TX:
- usbp->usb_ep0next += usbp->usb_ep0lastsize;
- usbp->usb_ep0max -= usbp->usb_ep0lastsize;
- usbp->usb_ep0n -= usbp->usb_ep0lastsize;
-
- /* The final condition is when the requested size has been transmitted or
- when a packet has been sent with size less than the maximum packet
- size.*/
- if ((usbp->usb_ep0max == 0) ||
- (usbp->usb_ep0lastsize < usbp->usb_ep[0]->uep_config->uepc_in_maxsize))
- usbp->usb_ep0state = USB_EP0_WAITING_STS;
- else {
- usbp->usb_ep0lastsize =
- usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_in_maxsize ?
- usbp->usb_ep[0]->uep_config->uepc_in_maxsize :
- usbp->usb_ep0n;
- usb_lld_write(usbp, 0, usbp->usb_ep0next, usbp->usb_ep0lastsize);
- }
+ max = usb_lld_fetch_word(&usbp->setup[6]);
+ /* If the transmitted size is less than the requested size and it is a
+ multiple of the maximum packet size then a zero size packet must be
+ transmitted.*/
+ if ((usbp->ep0n < max) &&
+ ((usbp->ep0n % usbp->epc[0]->in_maxsize) == 0)) {
+ usb_lld_start_in(usbp, 0, NULL, 0);
+ return;
+ }
+
+ /* Transmit phase over, receiving the zero sized status packet.*/
+ usbp->ep0state = USB_EP0_WAITING_STS;
+ usb_lld_start_out(usbp, 0, NULL, 0);
return;
case USB_EP0_SENDING_STS:
- if (usbp->usb_ep0endcb)
- usbp->usb_ep0endcb(usbp);
-
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ /* Status packet sent, invoking the callback if defined.*/
+ if (usbp->ep0endcb != NULL)
+ usbp->ep0endcb(usbp);
+ usbp->ep0state = USB_EP0_WAITING_SETUP;
return;
default:
;
}
- /* Error response.*/
+ /* Error response, the state machine goes into an error state, the low
+ level layer will have to reset it to USB_EP0_WAITING_SETUP after
+ receiving a SETUP packet.*/
usb_lld_stall_in(usbp, 0);
usb_lld_stall_out(usbp, 0);
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_STALLED);
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED);
+ usbp->ep0state = USB_EP0_ERROR;
}
/**
@@ -477,72 +655,33 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
* @notapi
*/
void _usb_ep0out(USBDriver *usbp, usbep_t ep) {
- size_t n, size;
- uint8_t buf[1];
(void)ep;
- switch (usbp->usb_ep0state) {
- case USB_EP0_WAITING_SETUP:
- /* SETUP packet handling.*/
- n = usb_lld_read(usbp, 0, usbp->usb_setup, 8);
- if (n != 8)
- break;
-
- /* First verify if the application has an handler installed for this
- request.*/
- if (!(usbp->usb_config->uc_requests_hook_cb) ||
- !(usbp->usb_config->uc_requests_hook_cb(usbp))) {
- /* Invoking the default handler, if this fails then stalls the
- endpoint zero as error.*/
- if (((usbp->usb_setup[0] & USB_RTYPE_TYPE_MASK) != USB_RTYPE_TYPE_STD) ||
- !default_handler(usbp))
- break;
- }
-
- /* Transfer preparation. The request handler must have populated
- correctly the fields usb_ep0next, usb_ep0n and usb_ep0endcb using
- the macro usbSetupTransfer().*/
- usbp->usb_ep0max = usb_lld_fetch_word(&usbp->usb_setup[6]);
- if ((usbp->usb_setup[0] & USB_RTYPE_DIR_MASK) == USB_RTYPE_DIR_DEV2HOST)
- start_tx_ep0(usbp);
- else
- start_rx_ep0(usbp);
- return;
+ switch (usbp->ep0state) {
case USB_EP0_RX:
- /* Check for buffer overflow.*/
- n = size = usb_lld_get_readable(usbp, 0);
- if (n > usbp->usb_ep0n)
- n = usbp->usb_ep0n;
- /* Fetching received data packet.*/
- n = usb_lld_read(usbp, 0, usbp->usb_ep0next, n);
- if (n > usbp->usb_ep0max)
- break;
- usbp->usb_ep0max -= size;
- usbp->usb_ep0n -= n;
- usbp->usb_ep0next += n;
- if (usbp->usb_ep0max == 0) {
- usb_lld_write(usbp, 0, NULL, 0);
- usbp->usb_ep0state = USB_EP0_SENDING_STS;
- }
+ /* Receive phase over, sending the zero sized status packet.*/
+ usbp->ep0state = USB_EP0_SENDING_STS;
+ usb_lld_start_in(usbp, 0, NULL, 0);
return;
case USB_EP0_WAITING_STS:
- /* STATUS received packet handling, it must be zero sized.*/
- n = usb_lld_read(usbp, 0, buf, 1);
- if (n != 0)
+ /* Status packet received, it must be zero sized, invoking the callback
+ if defined.*/
+ if (usbGetReceiveTransactionSizeI(usbp, 0) != 0)
break;
- if (usbp->usb_ep0endcb)
- usbp->usb_ep0endcb(usbp);
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ if (usbp->ep0endcb != NULL)
+ usbp->ep0endcb(usbp);
+ usbp->ep0state = USB_EP0_WAITING_SETUP;
return;
default:
;
}
- /* Error response.*/
+ /* Error response, the state machine goes into an error state, the low
+ level layer will have to reset it to USB_EP0_WAITING_SETUP after
+ receiving a SETUP packet.*/
usb_lld_stall_in(usbp, 0);
usb_lld_stall_out(usbp, 0);
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_STALLED);
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED);
+ usbp->ep0state = USB_EP0_ERROR;
}
#endif /* HAL_USE_USB */
diff --git a/os/hal/templates/adc_lld.c b/os/hal/templates/adc_lld.c
index 54622beb7..eea062160 100644
--- a/os/hal/templates/adc_lld.c
+++ b/os/hal/templates/adc_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -83,6 +84,10 @@ void adc_lld_start(ADCDriver *adcp) {
*/
void adc_lld_stop(ADCDriver *adcp) {
+ if (adcp->state == ADC_READY) {
+ /* Clock de-activation.*/
+
+ }
}
/**
diff --git a/os/hal/templates/adc_lld.h b/os/hal/templates/adc_lld.h
index 54d78fd44..5f04d221b 100644
--- a/os/hal/templates/adc_lld.h
+++ b/os/hal/templates/adc_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -86,15 +87,15 @@ typedef struct {
/**
* @brief Enables the circular buffer mode for the group.
*/
- bool_t acg_circular;
+ bool_t circular;
/**
* @brief Number of the analog channels belonging to the conversion group.
*/
- adc_channels_num_t acg_num_channels;
+ adc_channels_num_t num_channels;
/**
* @brief Callback function associated to the group or @p NULL.
*/
- adccallback_t acg_endcb;
+ adccallback_t end_cb;
/* End of the mandatory fields.*/
} ADCConversionGroup;
@@ -117,37 +118,37 @@ struct ADCDriver {
/**
* @brief Driver state.
*/
- adcstate_t ad_state;
+ adcstate_t state;
/**
* @brief Current configuration data.
*/
- const ADCConfig *ad_config;
+ const ADCConfig *config;
/**
* @brief Current samples buffer pointer or @p NULL.
*/
- adcsample_t *ad_samples;
+ adcsample_t *samples;
/**
* @brief Current samples buffer depth or @p 0.
*/
- size_t ad_depth;
+ size_t depth;
/**
* @brief Current conversion group pointer or @p NULL.
*/
- const ADCConversionGroup *ad_grpp;
+ const ADCConversionGroup *grpp;
#if ADC_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
- Thread *ad_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the peripheral.
*/
- Mutex ad_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore ad_semaphore;
+ Semaphore semaphore;
#endif
#endif /* ADC_USE_MUTUAL_EXCLUSION */
#if defined(ADC_DRIVER_EXT_FIELDS)
diff --git a/os/hal/templates/can_lld.c b/os/hal/templates/can_lld.c
index 2dc92f169..ae0ca9607 100644
--- a/os/hal/templates/can_lld.c
+++ b/os/hal/templates/can_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -80,7 +81,7 @@ void can_lld_start(CANDriver *canp) {
void can_lld_stop(CANDriver *canp) {
/* If in ready state then disables the CAN peripheral.*/
- if (canp->cd_state == CAN_READY) {
+ if (canp->state == CAN_READY) {
}
}
diff --git a/os/hal/templates/can_lld.h b/os/hal/templates/can_lld.h
index 37ce7f157..d07bd78cc 100644
--- a/os/hal/templates/can_lld.h
+++ b/os/hal/templates/can_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -82,22 +83,22 @@ typedef uint32_t canstatus_t;
*/
typedef struct {
struct {
- uint8_t cf_DLC:4; /**< @brief Data length. */
- uint8_t cf_RTR:1; /**< @brief Frame type. */
- uint8_t cf_IDE:1; /**< @brief Identifier type. */
+ uint8_t DLC:4; /**< @brief Data length. */
+ uint8_t RTR:1; /**< @brief Frame type. */
+ uint8_t IDE:1; /**< @brief Identifier type. */
};
union {
struct {
- uint32_t cf_SID:11; /**< @brief Standard identifier.*/
+ uint32_t SID:11; /**< @brief Standard identifier.*/
};
struct {
- uint32_t cf_EID:29; /**< @brief Extended identifier.*/
+ uint32_t EID:29; /**< @brief Extended identifier.*/
};
};
union {
- uint8_t cf_data8[8]; /**< @brief Frame data. */
- uint16_t cf_data16[4]; /**< @brief Frame data. */
- uint32_t cf_data32[2]; /**< @brief Frame data. */
+ uint8_t data8[8]; /**< @brief Frame data. */
+ uint16_t data16[4]; /**< @brief Frame data. */
+ uint32_t data32[2]; /**< @brief Frame data. */
};
} CANTxFrame;
@@ -109,22 +110,22 @@ typedef struct {
*/
typedef struct {
struct {
- uint8_t cf_DLC:4; /**< @brief Data length. */
- uint8_t cf_RTR:1; /**< @brief Frame type. */
- uint8_t cf_IDE:1; /**< @brief Identifier type. */
+ uint8_t DLC:4; /**< @brief Data length. */
+ uint8_t RTR:1; /**< @brief Frame type. */
+ uint8_t IDE:1; /**< @brief Identifier type. */
};
union {
struct {
- uint32_t cf_SID:11; /**< @brief Standard identifier.*/
+ uint32_t SID:11; /**< @brief Standard identifier.*/
};
struct {
- uint32_t cf_EID:29; /**< @brief Extended identifier.*/
+ uint32_t EID:29; /**< @brief Extended identifier.*/
};
};
union {
- uint8_t cf_data8[8]; /**< @brief Frame data. */
- uint16_t cf_data16[4]; /**< @brief Frame data. */
- uint32_t cf_data32[2]; /**< @brief Frame data. */
+ uint8_t data8[8]; /**< @brief Frame data. */
+ uint16_t data16[4]; /**< @brief Frame data. */
+ uint32_t data32[2]; /**< @brief Frame data. */
};
} CANRxFrame;
@@ -155,19 +156,19 @@ typedef struct {
/**
* @brief Driver state.
*/
- canstate_t cd_state;
+ canstate_t state;
/**
* @brief Current configuration data.
*/
- const CANConfig *cd_config;
+ const CANConfig *config;
/**
* @brief Transmission queue semaphore.
*/
- Semaphore cd_txsem;
+ Semaphore txsem;
/**
* @brief Receive queue semaphore.
*/
- Semaphore cd_rxsem;
+ Semaphore rxsem;
/**
* @brief One or more frames become available.
* @note After broadcasting this event it will not be broadcasted again
@@ -177,28 +178,28 @@ typedef struct {
* invoking @p chReceive() when listening to this event. This behavior
* minimizes the interrupt served by the system because CAN traffic.
*/
- EventSource cd_rxfull_event;
+ EventSource rxfull_event;
/**
* @brief One or more transmission slots become available.
*/
- EventSource cd_txempty_event;
+ EventSource txempty_event;
/**
* @brief A CAN bus error happened.
*/
- EventSource cd_error_event;
+ EventSource error_event;
/**
* @brief Error flags set when an error event is broadcasted.
*/
- canstatus_t cd_status;
+ canstatus_t status;
#if CAN_USE_SLEEP_MODE || defined (__DOXYGEN__)
/**
* @brief Entering sleep state event.
*/
- EventSource cd_sleep_event;
+ EventSource sleep_event;
/**
* @brief Exiting sleep state event.
*/
- EventSource cd_wakeup_event;
+ EventSource wakeup_event;
#endif /* CAN_USE_SLEEP_MODE */
/* End of the mandatory fields.*/
} CANDriver;
diff --git a/os/hal/templates/gpt_lld.c b/os/hal/templates/gpt_lld.c
new file mode 100644
index 000000000..1ee010603
--- /dev/null
+++ b/os/hal/templates/gpt_lld.c
@@ -0,0 +1,135 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/gpt_lld.c
+ * @brief GPT Driver subsystem low level driver source template.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level GPT driver initialization.
+ *
+ * @notapi
+ */
+void gpt_lld_init(void) {
+
+}
+
+/**
+ * @brief Configures and activates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_start(GPTDriver *gptp) {
+ uint16_t psc;
+
+ if (gptp->state == GPT_STOP) {
+ /* Clock activation.*/
+
+ }
+ /* Configuration.*/
+}
+
+/**
+ * @brief Deactivates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop(GPTDriver *gptp) {
+
+ if (gptp->state == GPT_READY) {
+ /* Clock de-activation.*/
+
+ }
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] period period in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period) {
+
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop_timer(GPTDriver *gptp) {
+
+}
+
+/**
+ * @brief Starts the timer in one shot mode and waits for completion.
+ * @details This function specifically polls the timer waiting for completion
+ * in order to not have extra delays caused by interrupt servicing,
+ * this function is only recommended for short delays.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
+
+}
+
+#endif /* HAL_USE_GPT */
+
+/** @} */
diff --git a/os/hal/templates/gpt_lld.h b/os/hal/templates/gpt_lld.h
new file mode 100644
index 000000000..4053c9b7a
--- /dev/null
+++ b/os/hal/templates/gpt_lld.h
@@ -0,0 +1,134 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/gpt_lld.h
+ * @brief GPT Driver subsystem low level driver header template.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#ifndef _GPT_LLD_H_
+#define _GPT_LLD_H_
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT frequency type.
+ */
+typedef uint32_t gptfreq_t;
+
+/**
+ * @brief GPT counter type.
+ */
+typedef uint16_t gptcnt_t;
+
+/**
+ * @brief Type of a structure representing a GPT driver.
+ */
+typedef struct GPTDriver GPTDriver;
+
+/**
+ * @brief GPT notification callback type.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ */
+typedef void (*gptcallback_t)(GPTDriver *gptp);
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ gptfreq_t frequency;
+ /**
+ * @brief Timer callback pointer.
+ * @note This callback is invoked on GPT counter events.
+ */
+ gptcallback_t callback;
+ /* End of the mandatory fields.*/
+} GPTConfig;
+
+/**
+ * @brief Structure representing a GPT driver.
+ */
+struct GPTDriver {
+ /**
+ * @brief Driver state.
+ */
+ gptstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const GPTConfig *config;
+#if defined(GPT_DRIVER_EXT_FIELDS)
+ GPT_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void gpt_lld_init(void);
+ void gpt_lld_start(GPTDriver *gptp);
+ void gpt_lld_stop(GPTDriver *gptp);
+ void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval);
+ void gpt_lld_stop_timer(GPTDriver *gptp);
+ void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_GPT */
+
+#endif /* _GPT_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/templates/hal_lld.c b/os/hal/templates/hal_lld.c
index c0e561337..aead6dc43 100644
--- a/os/hal/templates/hal_lld.c
+++ b/os/hal/templates/hal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/hal_lld.h b/os/hal/templates/hal_lld.h
index ad78ba56b..87d150376 100644
--- a/os/hal/templates/hal_lld.h
+++ b/os/hal/templates/hal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/halconf.h b/os/hal/templates/halconf.h
index a1840f977..da86f61ed 100644
--- a/os/hal/templates/halconf.h
+++ b/os/hal/templates/halconf.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -55,6 +56,13 @@
#endif
/**
+ * @brief Enables the GPT subsystem.
+ */
+#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
+#define HAL_USE_GPT FALSE
+#endif
+
+/**
* @brief Enables the I2C subsystem.
*/
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
@@ -62,6 +70,13 @@
#endif
/**
+ * @brief Enables the ICU subsystem.
+ */
+#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
+#define HAL_USE_ICU FALSE
+#endif
+
+/**
* @brief Enables the MAC subsystem.
*/
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
@@ -83,6 +98,13 @@
#endif
/**
+ * @brief Enables the SDC subsystem.
+ */
+#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
+#define HAL_USE_SDC FALSE
+#endif
+
+/**
* @brief Enables the SERIAL subsystem.
*/
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
@@ -90,6 +112,13 @@
#endif
/**
+ * @brief Enables the SERIAL over USB subsystem.
+ */
+#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL_USB TRUE
+#endif
+
+/**
* @brief Enables the SPI subsystem.
*/
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
@@ -103,6 +132,13 @@
#define HAL_USE_UART TRUE
#endif
+/**
+ * @brief Enables the USB subsystem.
+ */
+#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
+#define HAL_USE_USB TRUE
+#endif
+
/*===========================================================================*/
/* ADC driver related settings. */
/*===========================================================================*/
@@ -207,6 +243,36 @@
/*===========================================================================*/
/*===========================================================================*/
+/* SDC driver related settings. */
+/*===========================================================================*/
+/**
+ * @brief Number of initialization attempts before rejecting the card.
+ * @note Attempts are performed at 10mS intevals.
+ */
+#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
+#define SDC_INIT_RETRY 100
+#endif
+
+/**
+ * @brief Include support for MMC cards.
+ * @note MMC support is not yet implemented so this option must be kept
+ * at @p FALSE.
+ */
+#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
+#define SDC_MMC_SUPPORT FALSE
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ */
+#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
+#define SDC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
/* SERIAL driver related settings. */
/*===========================================================================*/
diff --git a/os/hal/templates/i2c_lld.c b/os/hal/templates/i2c_lld.c
index d41f693ab..efd491857 100644
--- a/os/hal/templates/i2c_lld.c
+++ b/os/hal/templates/i2c_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/i2c_lld.h b/os/hal/templates/i2c_lld.h
index ea2b1a61e..a54e99a39 100644
--- a/os/hal/templates/i2c_lld.h
+++ b/os/hal/templates/i2c_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/icu_lld.c b/os/hal/templates/icu_lld.c
new file mode 100644
index 000000000..23596bc97
--- /dev/null
+++ b/os/hal/templates/icu_lld.c
@@ -0,0 +1,145 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/icu_lld.c
+ * @brief ICU Driver subsystem low level driver source template.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ICU driver initialization.
+ *
+ * @notapi
+ */
+void icu_lld_init(void) {
+
+}
+
+/**
+ * @brief Configures and activates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_start(ICUDriver *icup) {
+
+ if (icup->state == ICU_STOP) {
+ /* Clock activation.*/
+ }
+ /* Configuration.*/
+}
+
+/**
+ * @brief Deactivates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_stop(ICUDriver *icup) {
+
+ if (icup->state == ICU_READY) {
+ /* Clock deactivation.*/
+
+ }
+}
+
+/**
+ * @brief Enables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_enable(ICUDriver *icup) {
+
+}
+
+/**
+ * @brief Disables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_disable(ICUDriver *icup) {
+
+}
+
+/**
+ * @brief Returns the width of the latest pulse.
+ * @details The pulse width is defined as number of ticks between the start
+ * edge and the stop edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @notapi
+ */
+icucnt_t icu_lld_get_width(ICUDriver *icup) {
+
+}
+
+/**
+ * @brief Returns the width of the latest cycle.
+ * @details The cycle width is defined as number of ticks between a start
+ * edge and the next start edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @notapi
+ */
+icucnt_t icu_lld_get_period(ICUDriver *icup) {
+
+}
+
+#endif /* HAL_USE_ICU */
+
+/** @} */
diff --git a/os/hal/templates/icu_lld.h b/os/hal/templates/icu_lld.h
new file mode 100644
index 000000000..34549b76e
--- /dev/null
+++ b/os/hal/templates/icu_lld.h
@@ -0,0 +1,138 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/icu_lld.h
+ * @brief ICU Driver subsystem low level driver header template.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#ifndef _ICU_LLD_H_
+#define _ICU_LLD_H_
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ICU driver mode.
+ */
+typedef enum {
+ ICU_INPUT_ACTIVE_HIGH = 0, /**< Trigger on rising edge. */
+ ICU_INPUT_ACTIVE_LOW = 1, /**< Trigger on falling edge. */
+} icumode_t;
+
+/**
+ * @brief ICU frequency type.
+ */
+typedef uint32_t icufreq_t;
+
+/**
+ * @brief ICU counter type.
+ */
+typedef uint16_t icucnt_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Driver mode.
+ */
+ icumode_t mode;
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ icufreq_t frequency;
+ /**
+ * @brief Callback for pulse width measurement.
+ */
+ icucallback_t width_cb;
+ /**
+ * @brief Callback for cycle period measurement.
+ */
+ icucallback_t period_cb;
+ /* End of the mandatory fields.*/
+} ICUConfig;
+
+/**
+ * @brief Structure representing an ICU driver.
+ */
+struct ICUDriver {
+ /**
+ * @brief Driver state.
+ */
+ icustate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const ICUConfig *config;
+#if defined(ICU_DRIVER_EXT_FIELDS)
+ ICU_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void icu_lld_init(void);
+ void icu_lld_start(ICUDriver *icup);
+ void icu_lld_stop(ICUDriver *icup);
+ void icu_lld_enable(ICUDriver *icup);
+ void icu_lld_disable(ICUDriver *icup);
+ icucnt_t icu_lld_get_width(ICUDriver *icup);
+ icucnt_t icu_lld_get_period(ICUDriver *icup);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ICU */
+
+#endif /* _ICU_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/templates/mac_lld.c b/os/hal/templates/mac_lld.c
index 8049f29ec..c6cc7825b 100644
--- a/os/hal/templates/mac_lld.c
+++ b/os/hal/templates/mac_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/mac_lld.h b/os/hal/templates/mac_lld.h
index 869fa5db8..e8abe2941 100644
--- a/os/hal/templates/mac_lld.h
+++ b/os/hal/templates/mac_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -73,10 +74,10 @@
* architecture dependent, fields.
*/
typedef struct {
- Semaphore md_tdsem; /**< Transmit semaphore. */
- Semaphore md_rdsem; /**< Receive semaphore. */
+ Semaphore tdsem; /**< Transmit semaphore. */
+ Semaphore rdsem; /**< Receive semaphore. */
#if CH_USE_EVENTS
- EventSource md_rdevent; /**< Receive event source. */
+ EventSource rdevent; /**< Receive event source. */
#endif
/* End of the mandatory fields.*/
} MACDriver;
@@ -87,8 +88,8 @@ typedef struct {
* architecture dependent, fields.
*/
typedef struct {
- size_t td_offset; /**< Current write offset. */
- size_t td_size; /**< Available space size. */
+ size_t offset; /**< Current write offset. */
+ size_t size; /**< Available space size. */
/* End of the mandatory fields.*/
} MACTransmitDescriptor;
@@ -98,8 +99,8 @@ typedef struct {
* architecture dependent, fields.
*/
typedef struct {
- size_t rd_offset; /**< Current read offset. */
- size_t rd_size; /**< Available data size. */
+ size_t offset; /**< Current read offset. */
+ size_t size; /**< Available data size. */
/* End of the mandatory fields.*/
} MACReceiveDescriptor;
diff --git a/os/hal/templates/meta/driver.c b/os/hal/templates/meta/driver.c
index f75c5d380..c12103353 100644
--- a/os/hal/templates/meta/driver.c
+++ b/os/hal/templates/meta/driver.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,8 +68,8 @@ void xxxInit(void) {
*/
void xxxObjectInit(XXXDriver *xxxp) {
- xxxp->xxx_state = XXX_STOP;
- xxxp->xxx_config = NULL;
+ xxxp->state = XXX_STOP;
+ xxxp->config = NULL;
}
/**
@@ -84,12 +85,11 @@ void xxxStart(XXXDriver *xxxp, const XXXConfig *config) {
chDbgCheck((xxxp != NULL) && (config != NULL), "xxxStart");
chSysLock();
- chDbgAssert((xxxp->xxx_state == XXX_STOP) || (xxxp->xxx_state == XXX_READY),
- "xxxStart(), #1",
- "invalid state");
- xxxp->xxx_config = config;
+ chDbgAssert((xxxp->state == XXX_STOP) || (xxxp->state == XXX_READY),
+ "xxxStart(), #1", "invalid state");
+ xxxp->config = config;
xxx_lld_start(xxxp);
- xxxp->xxx_state = XXX_READY;
+ xxxp->state = XXX_READY;
chSysUnlock();
}
@@ -105,11 +105,10 @@ void xxxStop(XXXDriver *xxxp) {
chDbgCheck(xxxp != NULL, "xxxStop");
chSysLock();
- chDbgAssert((xxxp->xxx_state == XXX_STOP) || (xxxp->xxx_state == XXX_READY),
- "xxxStop(), #1",
- "invalid state");
+ chDbgAssert((xxxp->state == XXX_STOP) || (xxxp->state == XXX_READY),
+ "xxxStop(), #1", "invalid state");
xxx_lld_stop(xxxp);
- xxxp->xxx_state = XXX_STOP;
+ xxxp->state = XXX_STOP;
chSysUnlock();
}
diff --git a/os/hal/templates/meta/driver.h b/os/hal/templates/meta/driver.h
index 1014e871c..b4b07170b 100644
--- a/os/hal/templates/meta/driver.h
+++ b/os/hal/templates/meta/driver.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/meta/driver_lld.c b/os/hal/templates/meta/driver_lld.c
index 051dfac03..2cf87bf1f 100644
--- a/os/hal/templates/meta/driver_lld.c
+++ b/os/hal/templates/meta/driver_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -68,7 +69,7 @@ void xxx_lld_init(void) {
*/
void xxx_lld_start(XXXDriver *xxxp) {
- if (xxxp->xxx_state == XXX_STOP) {
+ if (xxxp->state == XXX_STOP) {
/* Clock activation.*/
}
/* Configuration.*/
@@ -83,6 +84,10 @@ void xxx_lld_start(XXXDriver *xxxp) {
*/
void xxx_lld_stop(XXXDriver *xxxp) {
+ if (xxxp->state == XXX_READY) {
+ /* Clock deactivation.*/
+
+ }
}
#endif /* HAL_USE_XXX */
diff --git a/os/hal/templates/meta/driver_lld.h b/os/hal/templates/meta/driver_lld.h
index 7d75bbaea..5af5a4174 100644
--- a/os/hal/templates/meta/driver_lld.h
+++ b/os/hal/templates/meta/driver_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,11 +68,11 @@ struct XXXDriver {
/**
* @brief Driver state.
*/
- xxxstate_t xxx_state;
+ xxxstate_t state;
/**
* @brief Current configuration data.
*/
- const XXXConfig *xxx_config;
+ const XXXConfig *config;
/* End of the mandatory fields.*/
};
diff --git a/os/hal/templates/pal_lld.c b/os/hal/templates/pal_lld.c
index 583b39236..5314ef4b2 100644
--- a/os/hal/templates/pal_lld.c
+++ b/os/hal/templates/pal_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/pal_lld.h b/os/hal/templates/pal_lld.h
index d2e151018..8272b7c30 100644
--- a/os/hal/templates/pal_lld.h
+++ b/os/hal/templates/pal_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/pwm_lld.c b/os/hal/templates/pwm_lld.c
index 7e904765a..67683d120 100644
--- a/os/hal/templates/pwm_lld.c
+++ b/os/hal/templates/pwm_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -68,7 +69,7 @@ void pwm_lld_init(void) {
*/
void pwm_lld_start(PWMDriver *pwmp) {
- if (pwmp->pd_state == PWM_STOP) {
+ if (pwmp->state == PWM_STOP) {
/* Clock activation.*/
}
/* Configuration.*/
@@ -86,23 +87,32 @@ void pwm_lld_stop(PWMDriver *pwmp) {
}
/**
- * @brief Determines whatever the PWM channel is already enabled.
+ * @brief Changes the period the PWM peripheral.
+ * @details This function changes the period of a PWM unit that has already
+ * been activated using @p pwmStart().
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The PWM unit period is changed to the new value.
+ * @note The function has effect at the next cycle start.
+ * @note If a period is specified that is shorter than the pulse width
+ * programmed in one of the channels then the behavior is not
+ * guaranteed.
*
- * @param[in] pwmp pointer to the @p PWMDriver object
- * @param[in] channel PWM channel identifier
- * @return The PWM channel status.
- * @retval FALSE the channel is not enabled.
- * @retval TRUE the channel is enabled.
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] period new cycle time in ticks
*
* @notapi
*/
-bool_t pwm_lld_is_enabled(PWMDriver *pwmp, pwmchannel_t channel) {
+void pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period) {
- return FALSE;
}
/**
* @brief Enables a PWM channel.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is active using the specified configuration.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
@@ -118,11 +128,17 @@ void pwm_lld_enable_channel(PWMDriver *pwmp,
/**
* @brief Disables a PWM channel.
- * @details The channel is disabled and its output line returned to the
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is disabled and its output line returned to the
* idle state.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
+ *
+ * @notapi
*/
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
diff --git a/os/hal/templates/pwm_lld.h b/os/hal/templates/pwm_lld.h
index 74fb280a7..c34694951 100644
--- a/os/hal/templates/pwm_lld.h
+++ b/os/hal/templates/pwm_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -54,6 +55,11 @@
/*===========================================================================*/
/**
+ * @brief PWM mode type.
+ */
+typedef uint32_t pwmmode_t;
+
+/**
* @brief PWM channel type.
*/
typedef uint8_t pwmchannel_t;
@@ -64,18 +70,6 @@ typedef uint8_t pwmchannel_t;
typedef uint16_t pwmcnt_t;
/**
- * @brief Type of a structure representing an PWM driver.
- */
-typedef struct PWMDriver PWMDriver;
-
-/**
- * @brief PWM notification callback type.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- */
-typedef void (*pwmcallback_t)(PWMDriver *pwmp);
-
-/**
* @brief PWM driver channel configuration structure.
* @note Some architectures may not be able to support the channel mode
* or the callback, in this case the fields are ignored.
@@ -84,13 +78,13 @@ typedef struct {
/**
* @brief Channel active logic level.
*/
- pwmmode_t pcc_mode;
+ pwmmode_t mode;
/**
* @brief Channel callback pointer.
* @note This callback is invoked on the channel compare event. If set to
* @p NULL then the callback is disabled.
*/
- pwmcallback_t pcc_callback;
+ pwmcallback_t callback;
/* End of the mandatory fields.*/
} PWMChannelConfig;
@@ -101,15 +95,27 @@ typedef struct {
*/
typedef struct {
/**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ uint32_t frequency;
+ /**
+ * @brief PWM period in ticks.
+ * @note The low level can use assertions in order to catch invalid
+ * period specifications.
+ */
+ pwmcnt_t period;
+ /**
* @brief Periodic callback pointer.
* @note This callback is invoked on PWM counter reset. If set to
* @p NULL then the callback is disabled.
*/
- pwmcallback_t pc_callback;
+ pwmcallback_t callback;
/**
* @brief Channels configurations.
*/
- PWMChannelConfig pc_channels[PWM_CHANNELS];
+ PWMChannelConfig channels[PWM_CHANNELS];
/* End of the mandatory fields.*/
} PWMConfig;
@@ -122,11 +128,15 @@ struct PWMDriver {
/**
* @brief Driver state.
*/
- pwmstate_t pd_state;
+ pwmstate_t state;
/**
* @brief Current configuration data.
*/
- const PWMConfig *pd_config;
+ const PWMConfig *config;
+ /**
+ * @brief Current PWM period in ticks.
+ */
+ pwmcnt_t period;
#if defined(PWM_DRIVER_EXT_FIELDS)
PWM_DRIVER_EXT_FIELDS
#endif
@@ -137,54 +147,6 @@ struct PWMDriver {
/* Driver macros. */
/*===========================================================================*/
-/**
- * @brief Converts from fraction to pulse width.
- * @note Be careful with rounding errors, this is integer math not magic.
- * You can specify tenths of thousandth but make sure you have the
- * proper hardware resolution by carefully choosing the clock source
- * and prescaler settings, see @p PWM_COMPUTE_PSC.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] numerator numerator of the fraction
- * @param[in] denominator percentage as an integer between 0 and numerator
- * @return The pulse width to be passed to @p pwmEnableChannel().
- *
- * @api
- */
-#define PWM_FRACTION_TO_WIDTH(pwmp, numerator, denominator) 0
-
-/**
- * @brief Converts from degrees to pulse width.
- * @note Be careful with rounding errors, this is integer math not magic.
- * You can specify hundredths of degrees but make sure you have the
- * proper hardware resolution by carefully choosing the clock source
- * and prescaler settings, see @p PWM_COMPUTE_PSC.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] degrees degrees as an integer between 0 and 36000
- * @return The pulse width to be passed to @p pwmEnableChannel().
- *
- * @api
- */
-#define PWM_DEGREES_TO_WIDTH(pwmp, degrees) \
- PWM_FRACTION_TO_WIDTH(pwmp, 36000, degrees)
-
-/**
- * @brief Converts from percentage to pulse width.
- * @note Be careful with rounding errors, this is integer math not magic.
- * You can specify tenths of thousandth but make sure you have the
- * proper hardware resolution by carefully choosing the clock source
- * and prescaler settings, see @p PWM_COMPUTE_PSC.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] percentage percentage as an integer between 0 and 10000
- * @return The pulse width to be passed to @p pwmEnableChannel().
- *
- * @api
- */
-#define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \
- PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage)
-
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@@ -195,7 +157,7 @@ extern "C" {
void pwm_lld_init(void);
void pwm_lld_start(PWMDriver *pwmp);
void pwm_lld_stop(PWMDriver *pwmp);
- bool_t pwm_lld_is_enabled(PWMDriver *pwmp, pwmchannel_t channel);
+ void pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period);
void pwm_lld_enable_channel(PWMDriver *pwmp,
pwmchannel_t channel,
pwmcnt_t width);
diff --git a/os/hal/templates/serial_lld.c b/os/hal/templates/serial_lld.c
index 406235767..8fe70f628 100644
--- a/os/hal/templates/serial_lld.c
+++ b/os/hal/templates/serial_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/serial_lld.h b/os/hal/templates/serial_lld.h
index 3c2e8a299..7d570c667 100644
--- a/os/hal/templates/serial_lld.h
+++ b/os/hal/templates/serial_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/spi_lld.c b/os/hal/templates/spi_lld.c
index 5b76e3bdf..c6162d7e0 100644
--- a/os/hal/templates/spi_lld.c
+++ b/os/hal/templates/spi_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -68,7 +69,7 @@ void spi_lld_init(void) {
*/
void spi_lld_start(SPIDriver *spip) {
- if (spip->spd_state == SPI_STOP) {
+ if (spip->state == SPI_STOP) {
/* Clock activation.*/
}
/* Configuration.*/
diff --git a/os/hal/templates/spi_lld.h b/os/hal/templates/spi_lld.h
index e985aa727..c261bb1d1 100644
--- a/os/hal/templates/spi_lld.h
+++ b/os/hal/templates/spi_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -66,9 +67,9 @@ typedef void (*spicallback_t)(SPIDriver *spip);
*/
typedef struct {
/**
- * @brief Operation complete callback.
+ * @brief Operation complete callback.
*/
- spicallback_t spc_endcb;
+ spicallback_t end_cb;
/* End of the mandatory fields.*/
} SPIConfig;
@@ -81,25 +82,25 @@ struct SPIDriver {
/**
* @brief Driver state.
*/
- spistate_t spd_state;
+ spistate_t state;
/**
* @brief Current configuration data.
*/
- const SPIConfig *spd_config;
+ const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
- * @brief Waiting thread.
+ * @brief Waiting thread.
*/
- Thread *spd_thread;
+ Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
- Mutex spd_mutex;
+ Mutex mutex;
#elif CH_USE_SEMAPHORES
- Semaphore spd_semaphore;
+ Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
diff --git a/os/hal/templates/uart_lld.c b/os/hal/templates/uart_lld.c
index ab0abeb55..21708858b 100644
--- a/os/hal/templates/uart_lld.c
+++ b/os/hal/templates/uart_lld.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/templates/uart_lld.h b/os/hal/templates/uart_lld.h
index 531e7f3ab..ca55f0108 100644
--- a/os/hal/templates/uart_lld.h
+++ b/os/hal/templates/uart_lld.h
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -90,23 +91,23 @@ typedef struct {
/**
* @brief End of transmission buffer callback.
*/
- uartcb_t uc_txend1;
+ uartcb_t txend1_cb;
/**
* @brief Physical end of transmission callback.
*/
- uartcb_t uc_txend2;
+ uartcb_t txend2_cb;
/**
* @brief Receive buffer filled callback.
*/
- uartcb_t uc_rxend;
+ uartcb_t rxend_cb;
/**
* @brief Character received while out if the @p UART_RECEIVE state.
*/
- uartccb_t uc_rxchar;
+ uartccb_t rxchar_cb;
/**
* @brief Receive error callback.
*/
- uartecb_t uc_rxerr;
+ uartecb_t rxerr_cb;
/* End of the mandatory fields.*/
} UARTConfig;
@@ -119,19 +120,19 @@ struct UARTDriver {
/**
* @brief Driver state.
*/
- uartstate_t ud_state;
+ uartstate_t state;
/**
* @brief Transmitter state.
*/
- uarttxstate_t ud_txstate;
+ uarttxstate_t txstate;
/**
* @brief Receiver state.
*/
- uartrxstate_t ud_rxstate;
+ uartrxstate_t rxstate;
/**
* @brief Current configuration data.
*/
- const UARTConfig *ud_config;
+ const UARTConfig *config;
#if defined(UART_DRIVER_EXT_FIELDS)
UART_DRIVER_EXT_FIELDS
#endif
diff --git a/os/hal/templates/usb_lld.c b/os/hal/templates/usb_lld.c
new file mode 100644
index 000000000..515fc5443
--- /dev/null
+++ b/os/hal/templates/usb_lld.c
@@ -0,0 +1,346 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/usb_lld.c
+ * @brief USB Driver subsystem low level driver source template.
+ *
+ * @addtogroup USB
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_USB || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported 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 EP0 initialization structure.
+ */
+static const USBEndpointConfig ep0config = {
+ USB_EP_MODE_TYPE_CTRL | USB_EP_MODE_TRANSACTION,
+ _usb_ep0in,
+ _usb_ep0out,
+ 0x40,
+ 0x40,
+ &ep0_state.in,
+ &ep0_state.out
+};
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level USB driver initialization.
+ *
+ * @notapi
+ */
+void usb_lld_init(void) {
+
+}
+
+/**
+ * @brief Configures and activates the USB peripheral.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_start(USBDriver *usbp) {
+
+ if (usbp->state == USB_STOP) {
+ /* Clock activation.*/
+
+ /* Reset procedure enforced on driver start.*/
+ _usb_reset(usbp);
+ }
+ /* Configuration.*/
+}
+
+/**
+ * @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) {
+
+ }
+}
+
+/**
+ * @brief USB low level reset routine.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_reset(USBDriver *usbp) {
+
+ /* Post reset initialization.*/
+
+ /* EP0 initialization.*/
+ usbp->epc[0] = &ep0config;
+ usb_lld_init_endpoint(usbp, 0);
+}
+
+/**
+ * @brief Sets the USB address.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_set_address(USBDriver *usbp) {
+
+}
+
+/**
+ * @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) {
+
+}
+
+/**
+ * @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) {
+
+}
+
+/**
+ * @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) {
+
+}
+
+/**
+ * @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) {
+
+}
+
+/**
+ * @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) {
+
+}
+
+/**
+ * @brief Reads a packet from the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @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
+ * @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(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+
+}
+
+/**
+ * @brief Writes a packet to the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to transmit the packet.
+ *
+ * @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(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+
+}
+
+/**
+ * @brief Starts a receive operation on an OUT endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the endpoint data
+ * @param[in] n maximum number of bytes to copy in the buffer
+ *
+ * @notapi
+ */
+void usb_lld_start_out(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+
+}
+
+/**
+ * @brief Starts a transmit operation on an IN endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the endpoint data
+ * @param[in] n maximum number of bytes to copy
+ *
+ * @notapi
+ */
+void usb_lld_start_in(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+
+}
+
+/**
+ * @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) {
+
+}
+
+/**
+ * @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) {
+
+}
+
+/**
+ * @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) {
+
+}
+
+/**
+ * @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) {
+
+}
+
+#endif /* HAL_USE_USB */
+
+/** @} */
diff --git a/os/hal/templates/usb_lld.h b/os/hal/templates/usb_lld.h
new file mode 100644
index 000000000..5a41c1c05
--- /dev/null
+++ b/os/hal/templates/usb_lld.h
@@ -0,0 +1,310 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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/usb_lld.h
+ * @brief USB Driver subsystem low level driver header template.
+ *
+ * @addtogroup USB
+ * @{
+ */
+
+#ifndef _USB_LLD_H_
+#define _USB_LLD_H_
+
+#if HAL_USE_USB || defined(__DOXYGEN__)
+
+#include "stm32_usb.h"
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Maximum endpoint address.
+ */
+#define USB_MAX_ENDPOINTS 4
+
+/**
+ * @brief This device requires the address change after the status packet.
+ */
+#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of an IN endpoint state structure.
+ */
+typedef struct {
+
+} USBInEndpointState;
+
+/**
+ * @brief Type of an OUT endpoint state structure.
+ */
+typedef struct {
+
+} 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 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.*/
+} 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.*/
+};
+
+/*===========================================================================*/
+/* 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 current frame number.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @return The current frame number.
+ *
+ * @notapi
+ */
+#define usb_lld_get_frame_number(usbp)
+
+/**
+ * @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)
+
+/**
+ * @brief Returns the exact size of a received packet.
+ * @pre The OUT endpoint must have been configured in packet 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_packet_size(usbp, ep)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#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(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ void usb_lld_write_packet(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
+ void usb_lld_start_out(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ void usb_lld_start_in(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
+ void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
+ void usb_lld_stall_out(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_ */
+
+/** @} */