aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/include
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal/include')
-rw-r--r--os/hal/include/adc.h290
-rw-r--r--os/hal/include/can.h154
-rw-r--r--os/hal/include/hal.h104
-rw-r--r--os/hal/include/hal_channels.h291
-rw-r--r--os/hal/include/hal_queues.h401
-rw-r--r--os/hal/include/hal_streams.h162
-rw-r--r--os/hal/include/icu.h194
-rw-r--r--os/hal/include/pal.h540
-rw-r--r--os/hal/include/pwm.h252
-rw-r--r--os/hal/include/serial.h312
-rw-r--r--os/hal/include/spi.h310
-rw-r--r--os/hal/include/st.h72
12 files changed, 3082 insertions, 0 deletions
diff --git a/os/hal/include/adc.h b/os/hal/include/adc.h
new file mode 100644
index 000000000..23d767732
--- /dev/null
+++ b/os/hal/include/adc.h
@@ -0,0 +1,290 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 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 adc.h
+ * @brief ADC Driver macros and structures.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#ifndef _ADC_H_
+#define _ADC_H_
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name ADC configuration options
+ * @{
+ */
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
+#define ADC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define ADC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ ADC_UNINIT = 0, /**< Not initialized. */
+ ADC_STOP = 1, /**< Stopped. */
+ ADC_READY = 2, /**< Ready. */
+ ADC_ACTIVE = 3, /**< Converting. */
+ ADC_COMPLETE = 4, /**< Conversion complete. */
+ ADC_ERROR = 5 /**< Conversion complete. */
+} adcstate_t;
+
+#include "adc_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Low Level driver helper macros
+ * @{
+ */
+#if ADC_USE_WAIT || defined(__DOXYGEN__)
+/**
+ * @brief Resumes a thread waiting for a conversion completion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+#define _adc_reset_i(adcp) \
+ osalThreadResumeI(&(adcp)->thread, MSG_RESET)
+
+/**
+ * @brief Resumes a thread waiting for a conversion completion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+#define _adc_reset_s(adcp) \
+ osalThreadResumeS(&(adcp)->thread, MSG_RESET)
+
+/**
+ * @brief Wakes up the waiting thread.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+#define _adc_wakeup_isr(adcp) { \
+ osalSysLockFromISR(); \
+ osalThreadResumeI(&(adcp)->thread, MSG_OK); \
+ osalSysUnlockFromISR(); \
+}
+
+/**
+ * @brief Wakes up the waiting thread with a timeout message.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+#define _adc_timeout_isr(adcp) { \
+ osalSysLockFromISR(); \
+ osalThreadResumeI(&(adcp)->thread, MSG_TIMEOUT); \
+ osalSysUnlockFromISR(); \
+}
+
+#else /* !ADC_USE_WAIT */
+#define _adc_reset_i(adcp)
+#define _adc_reset_s(adcp)
+#define _adc_wakeup_isr(adcp)
+#define _adc_timeout_isr(adcp)
+#endif /* !ADC_USE_WAIT */
+
+/**
+ * @brief Common ISR code, half buffer event.
+ * @details This code handles the portable part of the ISR code:
+ * - Callback invocation.
+ * .
+ * @note This macro is meant to be used in the low level drivers
+ * implementation only.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+#define _adc_isr_half_code(adcp) { \
+ if ((adcp)->grpp->end_cb != NULL) { \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth / 2); \
+ } \
+}
+
+/**
+ * @brief Common ISR code, full buffer event.
+ * @details This code handles the portable part of the ISR code:
+ * - Callback invocation.
+ * - Waiting thread wakeup, if any.
+ * - Driver state transitions.
+ * .
+ * @note This macro is meant to be used in the low level drivers
+ * implementation only.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+#define _adc_isr_full_code(adcp) { \
+ if ((adcp)->grpp->circular) { \
+ /* Callback handling.*/ \
+ if ((adcp)->grpp->end_cb != NULL) { \
+ if ((adcp)->depth > 1) { \
+ /* Invokes the callback passing the 2nd half of the buffer.*/ \
+ size_t half = (adcp)->depth / 2; \
+ size_t half_index = half * (adcp)->grpp->num_channels; \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples + half_index, half); \
+ } \
+ else { \
+ /* Invokes the callback passing the whole buffer.*/ \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth); \
+ } \
+ } \
+ } \
+ else { \
+ /* End conversion.*/ \
+ adc_lld_stop_conversion(adcp); \
+ 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)->depth / 2; \
+ size_t half_index = half * (adcp)->grpp->num_channels; \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples + half_index, half); \
+ } \
+ else { \
+ /* Invokes the callback passing the whole buffer.*/ \
+ (adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth); \
+ } \
+ if ((adcp)->state == ADC_COMPLETE) { \
+ (adcp)->state = ADC_READY; \
+ (adcp)->grpp = NULL; \
+ } \
+ } \
+ else { \
+ (adcp)->state = ADC_READY; \
+ (adcp)->grpp = NULL; \
+ } \
+ _adc_wakeup_isr(adcp); \
+ } \
+}
+
+/**
+ * @brief Common ISR code, error event.
+ * @details This code handles the portable part of the ISR code:
+ * - Callback invocation.
+ * - Waiting thread timeout signaling, if any.
+ * - Driver state transitions.
+ * .
+ * @note This macro is meant to be used in the low level drivers
+ * implementation only.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] err platform dependent error code
+ *
+ * @notapi
+ */
+#define _adc_isr_error_code(adcp, err) { \
+ adc_lld_stop_conversion(adcp); \
+ if ((adcp)->grpp->error_cb != NULL) { \
+ (adcp)->state = ADC_ERROR; \
+ (adcp)->grpp->error_cb(adcp, err); \
+ if ((adcp)->state == ADC_ERROR) \
+ (adcp)->state = ADC_READY; \
+ } \
+ (adcp)->grpp = NULL; \
+ _adc_timeout_isr(adcp); \
+}
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void adcInit(void);
+ void adcObjectInit(ADCDriver *adcp);
+ void adcStart(ADCDriver *adcp, const ADCConfig *config);
+ void adcStop(ADCDriver *adcp);
+ void adcStartConversion(ADCDriver *adcp,
+ const ADCConversionGroup *grpp,
+ adcsample_t *samples,
+ size_t depth);
+ void adcStartConversionI(ADCDriver *adcp,
+ const ADCConversionGroup *grpp,
+ adcsample_t *samples,
+ size_t depth);
+ void adcStopConversion(ADCDriver *adcp);
+ void adcStopConversionI(ADCDriver *adcp);
+#if ADC_USE_WAIT
+ msg_t adcConvert(ADCDriver *adcp,
+ const ADCConversionGroup *grpp,
+ adcsample_t *samples,
+ size_t depth);
+#endif
+#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
+ void adcAcquireBus(ADCDriver *adcp);
+ void adcReleaseBus(ADCDriver *adcp);
+#endif /* ADC_USE_MUTUAL_EXCLUSION */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ADC */
+
+#endif /* _ADC_H_ */
+
+/** @} */
diff --git a/os/hal/include/can.h b/os/hal/include/can.h
new file mode 100644
index 000000000..534f6f622
--- /dev/null
+++ b/os/hal/include/can.h
@@ -0,0 +1,154 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 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 can.h
+ * @brief CAN Driver macros and structures.
+ *
+ * @addtogroup CAN
+ * @{
+ */
+
+#ifndef _CAN_H_
+#define _CAN_H_
+
+#if HAL_USE_CAN || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name CAN status flags
+ * @{
+ */
+/**
+ * @brief Errors rate warning.
+ */
+#define CAN_LIMIT_WARNING 1
+/**
+ * @brief Errors rate error.
+ */
+#define CAN_LIMIT_ERROR 2
+/**
+ * @brief Bus off condition reached.
+ */
+#define CAN_BUS_OFF_ERROR 4
+/**
+ * @brief Framing error of some kind on the CAN bus.
+ */
+#define CAN_FRAMING_ERROR 8
+/**
+ * @brief Overflow in receive queue.
+ */
+#define CAN_OVERFLOW_ERROR 16
+/** @} */
+
+/**
+ * @brief Special mailbox identifier.
+ */
+#define CAN_ANY_MAILBOX 0
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name CAN configuration options
+ * @{
+ */
+/**
+ * @brief Sleep mode related APIs inclusion switch.
+ * @details This option can only be enabled if the CAN implementation supports
+ * the sleep mode, see the macro @p CAN_SUPPORTS_SLEEP exported by
+ * the underlying implementation.
+ */
+#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
+#define CAN_USE_SLEEP_MODE TRUE
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ CAN_UNINIT = 0, /**< Not initialized. */
+ CAN_STOP = 1, /**< Stopped. */
+ CAN_STARTING = 2, /**< Starting. */
+ CAN_READY = 3, /**< Ready. */
+ CAN_SLEEP = 4 /**< Sleep state. */
+} canstate_t;
+
+#include "can_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Converts a mailbox index to a bit mask.
+ */
+#define CAN_MAILBOX_TO_MASK(mbx) (1 << ((mbx) - 1))
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void canInit(void);
+ void canObjectInit(CANDriver *canp);
+ void canStart(CANDriver *canp, const CANConfig *config);
+ void canStop(CANDriver *canp);
+ msg_t canTransmit(CANDriver *canp,
+ canmbx_t mailbox,
+ const CANTxFrame *ctfp,
+ systime_t timeout);
+ msg_t canReceive(CANDriver *canp,
+ canmbx_t mailbox,
+ CANRxFrame *crfp,
+ systime_t timeout);
+#if CAN_USE_SLEEP_MODE
+ void canSleep(CANDriver *canp);
+ void canWakeup(CANDriver *canp);
+#endif /* CAN_USE_SLEEP_MODE */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_CAN */
+
+#endif /* _CAN_H_ */
+
+/** @} */
diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h
new file mode 100644
index 000000000..bafdb5419
--- /dev/null
+++ b/os/hal/include/hal.h
@@ -0,0 +1,104 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 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 hal.h
+ * @brief HAL subsystem header.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef _HAL_H_
+#define _HAL_H_
+
+#include "osal.h"
+#include "board.h"
+#include "halconf.h"
+
+#include "hal_lld.h"
+
+
+/* Abstract interfaces.*/
+#include "hal_streams.h"
+#include "hal_channels.h"
+//#include "io_block.h"
+//#include "mmcsd.h"
+
+/* Shared headers.*/
+#include "hal_queues.h"
+
+/* Normal drivers.*/
+#include "pal.h"
+#include "adc.h"
+#include "can.h"
+//#include "ext.h"
+//#include "gpt.h"
+//#include "i2c.h"
+#include "icu.h"
+//#include "mac.h"
+#include "pwm.h"
+//#include "rtc.h"
+#include "serial.h"
+//#include "sdc.h"
+#include "spi.h"
+#include "st.h"
+//#include "uart.h"
+//#include "usb.h"
+
+/* Complex drivers.*/
+//#include "mmc_spi.h"
+//#include "serial_usb.h"
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void halInit(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HAL_H_ */
+
+/** @} */
diff --git a/os/hal/include/hal_channels.h b/os/hal/include/hal_channels.h
new file mode 100644
index 000000000..bd9a26c77
--- /dev/null
+++ b/os/hal/include/hal_channels.h
@@ -0,0 +1,291 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 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 hal_channels.h
+ * @brief I/O channels access.
+ * @details This header defines an abstract interface useful to access generic
+ * I/O serial devices in a standardized way.
+ *
+ * @addtogroup IO_CHANNEL
+ * @details This module defines an abstract interface for I/O channels by
+ * extending the @p BaseSequentialStream interface.<br>
+ * Note that no code is present, I/O channels are just abstract
+ * interface like structures, you should look at the systems as
+ * to a set of abstract C++ classes (even if written in C).
+ * Specific device drivers can use/extend the interface and
+ * implement them.<br>
+ * This system has the advantage to make the access to channels
+ * independent from the implementation logic.
+ * @{
+ */
+
+#ifndef _HAL_CHANNELS_H_
+#define _HAL_CHANNELS_H_
+
+/**
+ * @brief @p BaseChannel specific methods.
+ */
+#define _base_channel_methods \
+ _base_sequential_stream_methods \
+ /* Channel put method with timeout specification.*/ \
+ msg_t (*putt)(void *instance, uint8_t b, systime_t time); \
+ /* Channel get method with timeout specification.*/ \
+ msg_t (*gett)(void *instance, systime_t time); \
+ /* Channel write method with timeout specification.*/ \
+ size_t (*writet)(void *instance, const uint8_t *bp, \
+ size_t n, systime_t time); \
+ /* Channel read method with timeout specification.*/ \
+ size_t (*readt)(void *instance, uint8_t *bp, size_t n, systime_t time);
+
+/**
+ * @brief @p BaseChannel specific data.
+ * @note It is empty because @p BaseChannel is only an interface without
+ * implementation.
+ */
+#define _base_channel_data \
+ _base_sequential_stream_data
+
+/**
+ * @extends BaseSequentialStreamVMT
+ *
+ * @brief @p BaseChannel virtual methods table.
+ */
+struct BaseChannelVMT {
+ _base_channel_methods
+};
+
+/**
+ * @extends BaseSequentialStream
+ *
+ * @brief Base channel class.
+ * @details This class represents a generic, byte-wide, I/O channel. This class
+ * introduces generic I/O primitives with timeout specification.
+ */
+typedef struct {
+ /** @brief Virtual Methods Table.*/
+ const struct BaseChannelVMT *vmt;
+ _base_channel_data
+} BaseChannel;
+
+/**
+ * @name Macro Functions (BaseChannel)
+ * @{
+ */
+/**
+ * @brief Channel blocking byte write with timeout.
+ * @details This function writes a byte value to a channel. If the channel
+ * is not ready to accept data then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @param[in] b the byte value to be written to the channel
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval STM_OK if the operation succeeded.
+ * @retval STM_TIMEOUT if the specified time expired.
+ * @retval STM_RESET if the channel associated queue (if any) was reset.
+ *
+ * @api
+ */
+#define chnPutTimeout(ip, b, time) ((ip)->vmt->putt(ip, b, time))
+
+/**
+ * @brief Channel blocking byte read with timeout.
+ * @details This function reads a byte value from a channel. If the data
+ * is not available then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return A byte value from the queue.
+ * @retval STM_TIMEOUT if the specified time expired.
+ * @retval STM_RESET if the channel associated queue (if any) has been
+ * reset.
+ *
+ * @api
+ */
+#define chnGetTimeout(ip, time) ((ip)->vmt->gett(ip, time))
+
+/**
+ * @brief Channel blocking write.
+ * @details The function writes data from a buffer to a channel. If the channel
+ * is not ready to accept data then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @param[out] bp pointer to the data buffer
+ * @param[in] n the maximum amount of data to be transferred
+ *
+ * @return The number of bytes transferred.
+ *
+ * @api
+ */
+#define chnWrite(ip, bp, n) chSequentialStreamWrite(ip, bp, n)
+
+/**
+ * @brief Channel blocking write with timeout.
+ * @details The function writes data from a buffer to a channel. If the channel
+ * is not ready to accept data then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @param[out] bp pointer to the data buffer
+ * @param[in] n the maximum amount of data to be transferred
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The number of bytes transferred.
+ *
+ * @api
+ */
+#define chnWriteTimeout(ip, bp, n, time) ((ip)->vmt->writet(ip, bp, n, time))
+
+/**
+ * @brief Channel blocking read.
+ * @details The function reads data from a channel into a buffer. If the data
+ * is not available then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @param[in] bp pointer to the data buffer
+ * @param[in] n the maximum amount of data to be transferred
+ *
+ * @return The number of bytes transferred.
+ *
+ * @api
+ */
+#define chnRead(ip, bp, n) chSequentialStreamRead(ip, bp, n)
+
+/**
+ * @brief Channel blocking read with timeout.
+ * @details The function reads data from a channel into a buffer. If the data
+ * is not available then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @param[in] bp pointer to the data buffer
+ * @param[in] n the maximum amount of data to be transferred
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The number of bytes transferred.
+ *
+ * @api
+ */
+#define chnReadTimeout(ip, bp, n, time) ((ip)->vmt->readt(ip, bp, n, time))
+/** @} */
+
+/**
+ * @name I/O status flags added to the event listener
+ * @{
+ */
+/** @brief No pending conditions.*/
+#define CHN_NO_ERROR 0
+/** @brief Connection happened.*/
+#define CHN_CONNECTED 1
+/** @brief Disconnection happened.*/
+#define CHN_DISCONNECTED 2
+/** @brief Data available in the input queue.*/
+#define CHN_INPUT_AVAILABLE 4
+/** @brief Output queue empty.*/
+#define CHN_OUTPUT_EMPTY 8
+/** @brief Transmission end.*/
+#define CHN_TRANSMISSION_END 16
+/** @} */
+
+/**
+ * @brief @p BaseAsynchronousChannel specific methods.
+ */
+#define _base_asynchronous_channel_methods \
+ _base_channel_methods \
+
+/**
+ * @brief @p BaseAsynchronousChannel specific data.
+ */
+#define _base_asynchronous_channel_data \
+ _base_channel_data \
+ /* I/O condition event source.*/ \
+ event_source_t event;
+
+/**
+ * @extends BaseChannelVMT
+ *
+ * @brief @p BaseAsynchronousChannel virtual methods table.
+ */
+struct BaseAsynchronousChannelVMT {
+ _base_asynchronous_channel_methods
+};
+
+/**
+ * @extends BaseChannel
+ *
+ * @brief Base asynchronous channel class.
+ * @details This class extends @p BaseChannel by adding event sources fields
+ * for asynchronous I/O for use in an event-driven environment.
+ */
+typedef struct {
+ /** @brief Virtual Methods Table.*/
+ const struct BaseAsynchronousChannelVMT *vmt;
+ _base_asynchronous_channel_data
+} BaseAsynchronousChannel;
+
+/**
+ * @name Macro Functions (BaseAsynchronousChannel)
+ * @{
+ */
+/**
+ * @brief Returns the I/O condition event source.
+ * @details The event source is broadcasted when an I/O condition happens.
+ *
+ * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived
+ * class
+ * @return A pointer to an @p EventSource object.
+ *
+ * @api
+ */
+#define chnGetEventSource(ip) (&((ip)->event))
+
+/**
+ * @brief Adds status flags to the listeners's flags mask.
+ * @details This function is usually called from the I/O ISRs in order to
+ * notify I/O conditions such as data events, errors, signal
+ * changes etc.
+ *
+ * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived
+ * class
+ * @param[in] flags condition flags to be added to the listener flags mask
+ *
+ * @iclass
+ */
+#define chnAddFlagsI(ip, flags) { \
+ osalEventBroadcastFlagsI(&(ip)->event, flags); \
+}
+/** @} */
+
+#endif /* _HAL_CHANNELS_H_ */
+
+/** @} */
diff --git a/os/hal/include/hal_queues.h b/os/hal/include/hal_queues.h
new file mode 100644
index 000000000..de5060bc3
--- /dev/null
+++ b/os/hal/include/hal_queues.h
@@ -0,0 +1,401 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 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 hal_queues.h
+ * @brief I/O Queues macros and structures.
+ *
+ * @addtogroup io_queues
+ * @{
+ */
+
+#ifndef _HAL_QUEUES_H_
+#define _HAL_QUEUES_H_
+
+/* The ChibiOS/RT kernel provides the following definitions by itself, this
+ check is performed in order to avoid conflicts. */
+#if !defined(_CHIBIOS_RT_) || !CH_USE_QUEUES
+
+/**
+ * @name Queue functions returned status value
+ * @{
+ */
+#define Q_OK MSG_OK /**< @brief Operation successful. */
+#define Q_TIMEOUT MSG_TIMEOUT /**< @brief Timeout condition. */
+#define Q_RESET MSG_RESET /**< @brief Queue has been reset. */
+#define Q_EMPTY -3 /**< @brief Queue empty. */
+#define Q_FULL -4 /**< @brief Queue full, */
+/** @} */
+
+/**
+ * @brief Type of a generic I/O queue structure.
+ */
+typedef struct GenericQueue GenericQueue;
+
+/** @brief Queue notification callback type.*/
+typedef void (*qnotify_t)(GenericQueue *qp);
+
+/**
+ * @brief Generic I/O queue structure.
+ * @details This structure represents a generic Input or Output asymmetrical
+ * queue. The queue is asymmetrical because one end is meant to be
+ * accessed from a thread context, and thus can be blocking, the other
+ * end is accessible from interrupt handlers or from within a kernel
+ * lock zone (see <b>I-Locked</b> and <b>S-Locked</b> states in
+ * @ref system_states) and is non-blocking.
+ */
+struct GenericQueue {
+ threads_queue_t q_waiting; /**< @brief Waiting thread. */
+ size_t q_counter; /**< @brief Resources counter. */
+ uint8_t *q_buffer; /**< @brief Pointer to the queue buffer.*/
+ uint8_t *q_top; /**< @brief Pointer to the first
+ location after the buffer. */
+ uint8_t *q_wrptr; /**< @brief Write pointer. */
+ uint8_t *q_rdptr; /**< @brief Read pointer. */
+ qnotify_t q_notify; /**< @brief Data notification callback. */
+ void *q_link; /**< @brief Application defined field. */
+};
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Returns the queue's buffer size.
+ *
+ * @param[in] qp pointer to a @p GenericQueue structure.
+ * @return The buffer size.
+ *
+ * @iclass
+ */
+#define qSizeI(qp) ((size_t)((qp)->q_top - (qp)->q_buffer))
+
+/**
+ * @brief Queue space.
+ * @details Returns the used space if used on an input queue or the empty
+ * space if used on an output queue.
+ *
+ * @param[in] qp pointer to a @p GenericQueue structure.
+ * @return The buffer space.
+ *
+ * @iclass
+ */
+#define qSpaceI(qp) ((qp)->q_counter)
+
+/**
+ * @brief Returns the queue application-defined link.
+ * @note This function can be called in any context.
+ *
+ * @param[in] qp pointer to a @p GenericQueue structure.
+ * @return The application-defined link.
+ *
+ * @special
+ */
+#define qGetLink(qp) ((qp)->q_link)
+/** @} */
+
+/**
+ * @extends GenericQueue
+ *
+ * @brief Type of an input queue structure.
+ * @details This structure represents a generic asymmetrical input queue.
+ * Writing to the queue is non-blocking and can be performed from
+ * interrupt handlers or from within a kernel lock zone (see
+ * <b>I-Locked</b> and <b>S-Locked</b> states in @ref system_states).
+ * Reading the queue can be a blocking operation and is supposed to
+ * be performed by a system thread.
+ */
+typedef GenericQueue InputQueue;
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Returns the filled space into an input queue.
+ *
+ * @param[in] iqp pointer to an @p InputQueue structure
+ * @return The number of full bytes in the queue.
+ * @retval 0 if the queue is empty.
+ *
+ * @iclass
+ */
+#define iqGetFullI(iqp) qSpaceI(iqp)
+
+/**
+ * @brief Returns the empty space into an input queue.
+ *
+ * @param[in] iqp pointer to an @p InputQueue structure
+ * @return The number of empty bytes in the queue.
+ * @retval 0 if the queue is full.
+ *
+ * @iclass
+ */
+#define iqGetEmptyI(iqp) (qSizeI(iqp) - qSpaceI(iqp))
+
+/**
+ * @brief Evaluates to @p TRUE if the specified input queue is empty.
+ *
+ * @param[in] iqp pointer to an @p InputQueue structure.
+ * @return The queue status.
+ * @retval FALSE if the queue is not empty.
+ * @retval TRUE if the queue is empty.
+ *
+ * @iclass
+ */
+#define iqIsEmptyI(iqp) ((bool_t)(qSpaceI(iqp) <= 0))
+
+/**
+ * @brief Evaluates to @p TRUE if the specified input queue is full.
+ *
+ * @param[in] iqp pointer to an @p InputQueue structure.
+ * @return The queue status.
+ * @retval FALSE if the queue is not full.
+ * @retval TRUE if the queue is full.
+ *
+ * @iclass
+ */
+#define iqIsFullI(iqp) ((bool_t)(((iqp)->q_wrptr == (iqp)->q_rdptr) && \
+ ((iqp)->q_counter != 0)))
+
+/**
+ * @brief Input queue read.
+ * @details This function reads a byte value from an input queue. If the queue
+ * is empty then the calling thread is suspended until a byte arrives
+ * in the queue.
+ *
+ * @param[in] iqp pointer to an @p InputQueue structure
+ * @return A byte value from the queue.
+ * @retval Q_RESET if the queue has been reset.
+ *
+ * @api
+ */
+#define iqGet(iqp) iqGetTimeout(iqp, TIME_INFINITE)
+/** @} */
+
+/**
+ * @brief Data part of a static input queue initializer.
+ * @details This macro should be used when statically initializing an
+ * input queue that is part of a bigger structure.
+ *
+ * @param[in] name the name of the input queue variable
+ * @param[in] buffer pointer to the queue buffer area
+ * @param[in] size size of the queue buffer area
+ * @param[in] inotify input notification callback pointer
+ * @param[in] link application defined pointer
+ */
+#define _INPUTQUEUE_DATA(name, buffer, size, inotify, link) { \
+ NULL, \
+ 0, \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer) + (size), \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer), \
+ (inotify), \
+ (link) \
+}
+
+/**
+ * @brief Static input queue initializer.
+ * @details Statically initialized input queues require no explicit
+ * initialization using @p iqInit().
+ *
+ * @param[in] name the name of the input queue variable
+ * @param[in] buffer pointer to the queue buffer area
+ * @param[in] size size of the queue buffer area
+ * @param[in] inotify input notification callback pointer
+ * @param[in] link application defined pointer
+ */
+#define INPUTQUEUE_DECL(name, buffer, size, inotify, link) \
+ InputQueue name = _INPUTQUEUE_DATA(name, buffer, size, inotify, link)
+
+/**
+ * @extends GenericQueue
+ *
+ * @brief Type of an output queue structure.
+ * @details This structure represents a generic asymmetrical output queue.
+ * Reading from the queue is non-blocking and can be performed from
+ * interrupt handlers or from within a kernel lock zone (see
+ * <b>I-Locked</b> and <b>S-Locked</b> states in @ref system_states).
+ * Writing the queue can be a blocking operation and is supposed to
+ * be performed by a system thread.
+ */
+typedef GenericQueue OutputQueue;
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Returns the filled space into an output queue.
+ *
+ * @param[in] oqp pointer to an @p OutputQueue structure
+ * @return The number of full bytes in the queue.
+ * @retval 0 if the queue is empty.
+ *
+ * @iclass
+ */
+#define oqGetFullI(oqp) (qSizeI(oqp) - qSpaceI(oqp))
+
+/**
+ * @brief Returns the empty space into an output queue.
+ *
+ * @param[in] oqp pointer to an @p OutputQueue structure
+ * @return The number of empty bytes in the queue.
+ * @retval 0 if the queue is full.
+ *
+ * @iclass
+ */
+#define oqGetEmptyI(oqp) qSpaceI(oqp)
+
+/**
+ * @brief Evaluates to @p TRUE if the specified output queue is empty.
+ *
+ * @param[in] oqp pointer to an @p OutputQueue structure.
+ * @return The queue status.
+ * @retval FALSE if the queue is not empty.
+ * @retval TRUE if the queue is empty.
+ *
+ * @iclass
+ */
+#define oqIsEmptyI(oqp) ((bool_t)(((oqp)->q_wrptr == (oqp)->q_rdptr) && \
+ ((oqp)->q_counter != 0)))
+
+/**
+ * @brief Evaluates to @p TRUE if the specified output queue is full.
+ *
+ * @param[in] oqp pointer to an @p OutputQueue structure.
+ * @return The queue status.
+ * @retval FALSE if the queue is not full.
+ * @retval TRUE if the queue is full.
+ *
+ * @iclass
+ */
+#define oqIsFullI(oqp) ((bool_t)(qSpaceI(oqp) <= 0))
+
+/**
+ * @brief Output queue write.
+ * @details This function writes a byte value to an output queue. If the queue
+ * is full then the calling thread is suspended until there is space
+ * in the queue.
+ *
+ * @param[in] oqp pointer to an @p OutputQueue structure
+ * @param[in] b the byte value to be written in the queue
+ * @return The operation status.
+ * @retval Q_OK if the operation succeeded.
+ * @retval Q_RESET if the queue has been reset.
+ *
+ * @api
+ */
+#define oqPut(oqp, b) oqPutTimeout(oqp, b, TIME_INFINITE)
+ /** @} */
+
+/**
+ * @brief Data part of a static output queue initializer.
+ * @details This macro should be used when statically initializing an
+ * output queue that is part of a bigger structure.
+ *
+ * @param[in] name the name of the output queue variable
+ * @param[in] buffer pointer to the queue buffer area
+ * @param[in] size size of the queue buffer area
+ * @param[in] onotify output notification callback pointer
+ * @param[in] link application defined pointer
+ */
+#define _OUTPUTQUEUE_DATA(name, buffer, size, onotify, link) { \
+ NULL, \
+ (size), \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer) + (size), \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer), \
+ (onotify), \
+ (link) \
+}
+
+/**
+ * @brief Static output queue initializer.
+ * @details Statically initialized output queues require no explicit
+ * initialization using @p oqInit().
+ *
+ * @param[in] name the name of the output queue variable
+ * @param[in] buffer pointer to the queue buffer area
+ * @param[in] size size of the queue buffer area
+ * @param[in] onotify output notification callback pointer
+ * @param[in] link application defined pointer
+ */
+#define OUTPUTQUEUE_DECL(name, buffer, size, onotify, link) \
+ OutputQueue name = _OUTPUTQUEUE_DATA(name, buffer, size, onotify, link)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void iqInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy,
+ void *link);
+ void iqResetI(InputQueue *iqp);
+ msg_t iqPutI(InputQueue *iqp, uint8_t b);
+ msg_t iqGetTimeout(InputQueue *iqp, systime_t time);
+ size_t iqReadTimeout(InputQueue *iqp, uint8_t *bp,
+ size_t n, systime_t time);
+
+ void oqInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy,
+ void *link);
+ void oqResetI(OutputQueue *oqp);
+ msg_t oqPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time);
+ msg_t oqGetI(OutputQueue *oqp);
+ size_t oqWriteTimeout(OutputQueue *oqp, const uint8_t *bp,
+ size_t n, systime_t time);
+#ifdef __cplusplus
+}
+#endif
+
+
+#else /* defined(_CHIBIOS_RT_) && CH_USE_QUEUES */
+
+/* If ChibiOS is being used and its own queues subsystem is activated then
+ this module will use the ChibiOS queues code.*/
+#define qSizeI(qp) chQSizeI(qp)
+#define qSpaceI(qp) chQSpaceI(qp)
+#define qGetLink(qp) chQGetLink(qp)
+#define iqGetFullI(iqp) chIQGetFullI(iqp)
+#define iqGetEmptyI(iqp) chIQGetEmptyI(iqp)
+#define iqIsEmptyI(iqp) chIQIsEmptyI(iqp)
+#define iqIsFullI(iqp) chIQIsFullI(iqp)
+#define iqGet(iqp) chIQGet(iqp)
+#define oqGetFullI(oqp) chOQGetFullI(oqp)
+#define oqGetEmptyI(oqp) chOQGetEmptyI(oqp)
+#define oqIsEmptyI(oqp) chOQIsEmptyI(oqp)
+#define oqIsFullI(oqp) chOQIsFullI(oqp)
+#define oqPut(oqp, b) chOQPut(oqp, b)
+#define iqInit(iqp, bp, size, infy, link) chIQInit(iqp, bp, size, infy, link)
+#define iqResetI(iqp) chIQResetI(iqp)
+#define iqPutI(iqp, b) chIQPutI(iqp, b)
+#define iqGetTimeout(iqp, time) chIQGetTimeout(iqp, time)
+#define iqReadTimeout(iqp, bp, n, time) chIQReadTimeout(iqp, bp, n, time)
+#define oqInit(oqp, bp, size, onfy, link) chOQInit(oqp, bp, size, onfy, link)
+#define oqResetI(oqp) chOQResetI(oqp)
+#define oqPutTimeout(oqp, b, time) chOQPutTimeout(oqp, b, time)
+#define oqGetI(oqp) chOQGetI(oqp)
+#define oqWriteTimeout(oqp, bp, n, time) chOQWriteTimeout(oqp, bp, n, time)
+
+#endif /* defined(_CHIBIOS_RT_) && CH_USE_QUEUES */
+
+#endif /* _HAL_QUEUES_H_ */
+
+/** @} */
diff --git a/os/hal/include/hal_streams.h b/os/hal/include/hal_streams.h
new file mode 100644
index 000000000..3440b7a53
--- /dev/null
+++ b/os/hal/include/hal_streams.h
@@ -0,0 +1,162 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 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 hal_streams.h
+ * @brief Data streams.
+ * @details This header defines abstract interfaces useful to access generic
+ * data streams in a standardized way.
+ *
+ * @addtogroup data_streams
+ * @details This module define an abstract interface for generic data streams.
+ * Note that no code is present, just abstract interfaces-like
+ * structures, you should look at the system as to a set of
+ * abstract C++ classes (even if written in C). This system
+ * has then advantage to make the access to data streams
+ * independent from the implementation logic.<br>
+ * The stream interface can be used as base class for high level
+ * object types such as files, sockets, serial ports, pipes etc.
+ * @{
+ */
+
+#ifndef _HAL_STREAMS_H_
+#define _HAL_STREAMS_H_
+
+/**
+ * @name Streams return codes
+ * @{
+ */
+#define STM_OK Q_OK
+#define STM_TIMEOUT Q_RESET
+#define STM_RESET Q_TIMEOUT
+/** @} */
+
+/* The ChibiOS/RT kernel provides the following definitions by itself, this
+ check is performed in order to avoid conflicts. */
+#if !defined(_CHIBIOS_RT_) || defined(__DOXYGEN__)
+
+/**
+ * @brief BaseSequentialStream specific methods.
+ */
+#define _base_sequential_stream_methods \
+ /* Stream write buffer method.*/ \
+ size_t (*write)(void *instance, const uint8_t *bp, size_t n); \
+ /* Stream read buffer method.*/ \
+ size_t (*read)(void *instance, uint8_t *bp, size_t n); \
+ /* Channel put method, blocking.*/ \
+ msg_t (*put)(void *instance, uint8_t b); \
+ /* Channel get method, blocking.*/ \
+ msg_t (*get)(void *instance); \
+
+/**
+ * @brief @p BaseSequentialStream specific data.
+ * @note It is empty because @p BaseSequentialStream is only an interface
+ * without implementation.
+ */
+#define _base_sequential_stream_data
+
+/**
+ * @brief @p BaseSequentialStream virtual methods table.
+ */
+struct BaseSequentialStreamVMT {
+ _base_sequential_stream_methods
+};
+
+/**
+ * @brief Base stream class.
+ * @details This class represents a generic blocking unbuffered sequential
+ * data stream.
+ */
+typedef struct {
+ /** @brief Virtual Methods Table.*/
+ const struct BaseSequentialStreamVMT *vmt;
+ _base_sequential_stream_data
+} BaseSequentialStream;
+
+/**
+ * @name Macro Functions (BaseSequentialStream)
+ * @{
+ */
+/**
+ * @brief Sequential Stream write.
+ * @details The function writes data from a buffer to a stream.
+ *
+ * @param[in] ip pointer to a @p BaseSequentialStream or derived class
+ * @param[in] bp pointer to the data buffer
+ * @param[in] n the maximum amount of data to be transferred
+ * @return The number of bytes transferred. The return value can
+ * be less than the specified number of bytes if an
+ * end-of-file condition has been met.
+ *
+ * @api
+ */
+#define streamSequentialStreamWrite(ip, bp, n) ((ip)->vmt->write(ip, bp, n))
+
+/**
+ * @brief Sequential Stream read.
+ * @details The function reads data from a stream into a buffer.
+ *
+ * @param[in] ip pointer to a @p BaseSequentialStream or derived class
+ * @param[out] bp pointer to the data buffer
+ * @param[in] n the maximum amount of data to be transferred
+ * @return The number of bytes transferred. The return value can
+ * be less than the specified number of bytes if an
+ * end-of-file condition has been met.
+ *
+ * @api
+ */
+#define streamSequentialStreamRead(ip, bp, n) ((ip)->vmt->read(ip, bp, n))
+
+/**
+ * @brief Sequential Stream blocking byte write.
+ * @details This function writes a byte value to a channel. If the channel
+ * is not ready to accept data then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @param[in] b the byte value to be written to the channel
+ *
+ * @return The operation status.
+ * @retval STM_OK if the operation succeeded.
+ * @retval STM_RESET if an end-of-file condition has been met.
+ *
+ * @api
+ */
+#define streamSequentialStreamPut(ip, b) ((ip)->vmt->put(ip, b))
+
+/**
+ * @brief Sequential Stream blocking byte read.
+ * @details This function reads a byte value from a channel. If the data
+ * is not available then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ *
+ * @return A byte value from the queue.
+ * @retval STM_RESET if an end-of-file condition has been met.
+ *
+ * @api
+ */
+#define streamSequentialStreamGet(ip) ((ip)->vmt->get(ip))
+/** @} */
+
+#endif /* !defined(_CHIBIOS_RT_)*/
+
+#endif /* _HAL_STREAMS_H_ */
+
+/** @} */
diff --git a/os/hal/include/icu.h b/os/hal/include/icu.h
new file mode 100644
index 000000000..ef42470cb
--- /dev/null
+++ b/os/hal/include/icu.h
@@ -0,0 +1,194 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 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. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @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.
+ * @note This function is meant to be invoked from the width capture
+ * callback only.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @special
+ */
+#define icuGetWidth(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.
+ * @note This function is meant to be invoked from the width capture
+ * callback only.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @special
+ */
+#define icuGetPeriod(icup) icu_lld_get_period(icup)
+/** @} */
+
+/**
+ * @name Low Level driver helper macros
+ * @{
+ */
+/**
+ * @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); \
+}
+
+/**
+ * @brief Common ISR code, ICU timer overflow event.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+#define _icu_isr_invoke_overflow_cb(icup) { \
+ (icup)->config->overflow_cb(icup); \
+}
+/** @} */
+
+/*===========================================================================*/
+/* 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/pal.h b/os/hal/include/pal.h
new file mode 100644
index 000000000..694da12ae
--- /dev/null
+++ b/os/hal/include/pal.h
@@ -0,0 +1,540 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 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 pal.h
+ * @brief I/O Ports Abstraction Layer macros, types and structures.
+ *
+ * @addtogroup PAL
+ * @{
+ */
+
+#ifndef _PAL_H_
+#define _PAL_H_
+
+#if HAL_USE_PAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name Pads mode constants
+ * @{
+ */
+/**
+ * @brief After reset state.
+ * @details The state itself is not specified and is architecture dependent,
+ * it is guaranteed to be equal to the after-reset state. It is
+ * usually an input state.
+ */
+#define PAL_MODE_RESET 0
+
+/**
+ * @brief Safe state for <b>unconnected</b> pads.
+ * @details The state itself is not specified and is architecture dependent,
+ * it may be mapped on @p PAL_MODE_INPUT_PULLUP,
+ * @p PAL_MODE_INPUT_PULLDOWN or @p PAL_MODE_OUTPUT_PUSHPULL for
+ * example.
+ */
+#define PAL_MODE_UNCONNECTED 1
+
+/**
+ * @brief Regular input high-Z pad.
+ */
+#define PAL_MODE_INPUT 2
+
+/**
+ * @brief Input pad with weak pull up resistor.
+ */
+#define PAL_MODE_INPUT_PULLUP 3
+
+/**
+ * @brief Input pad with weak pull down resistor.
+ */
+#define PAL_MODE_INPUT_PULLDOWN 4
+
+/**
+ * @brief Analog input mode.
+ */
+#define PAL_MODE_INPUT_ANALOG 5
+
+/**
+ * @brief Push-pull output pad.
+ */
+#define PAL_MODE_OUTPUT_PUSHPULL 6
+
+/**
+ * @brief Open-drain output pad.
+ */
+#define PAL_MODE_OUTPUT_OPENDRAIN 7
+/** @} */
+
+/**
+ * @name Logic level constants
+ * @{
+ */
+/**
+ * @brief Logical low state.
+ */
+#define PAL_LOW 0
+
+/**
+ * @brief Logical high state.
+ */
+#define PAL_HIGH 1
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+#include "pal_lld.h"
+
+/**
+ * @brief I/O bus descriptor.
+ * @details This structure describes a group of contiguous digital I/O lines
+ * that have to be handled as bus.
+ * @note I/O operations on a bus do not affect I/O lines on the same port but
+ * not belonging to the bus.
+ */
+typedef struct {
+ /**
+ * @brief Port identifier.
+ */
+ 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 mask;
+ /**
+ * @brief Offset, within the port, of the least significant bit of the bus.
+ */
+ uint_fast8_t offset;
+} IOBus;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Port bit helper macro.
+ * @details This macro calculates the mask of a bit within a port.
+ *
+ * @param[in] n bit position within the port
+ * @return The bit mask.
+ */
+#if !defined(PAL_PORT_BIT) || defined(__DOXYGEN__)
+#define PAL_PORT_BIT(n) ((ioportmask_t)(1 << (n)))
+#endif
+
+/**
+ * @brief Bits group mask helper.
+ * @details This macro calculates the mask of a bits group.
+ *
+ * @param[in] width group width
+ * @return The group mask.
+ */
+#if !defined(PAL_GROUP_MASK) || defined(__DOXYGEN__)
+#define PAL_GROUP_MASK(width) ((ioportmask_t)(1 << (width)) - 1)
+#endif
+
+/**
+ * @brief Data part of a static I/O bus initializer.
+ * @details This macro should be used when statically initializing an I/O bus
+ * that is part of a bigger structure.
+ *
+ * @param[in] name name of the IOBus variable
+ * @param[in] port I/O port descriptor
+ * @param[in] width bus width in bits
+ * @param[in] offset bus bit offset within the port
+ */
+#define _IOBUS_DATA(name, port, width, offset) \
+ {port, PAL_GROUP_MASK(width), offset}
+
+/**
+ * @brief Static I/O bus initializer.
+ *
+ * @param[in] name name of the IOBus variable
+ * @param[in] port I/O port descriptor
+ * @param[in] width bus width in bits
+ * @param[in] offset bus bit offset within the port
+ */
+#define IOBUS_DECL(name, port, width, offset) \
+ IOBus name = _IOBUS_DATA(name, port, width, offset)
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief PAL subsystem initialization.
+ * @note This function is implicitly invoked by @p halInit(), there is
+ * no need to explicitly initialize the driver.
+ *
+ * @param[in] config pointer to an architecture specific configuration
+ * structure. This structure is defined in the low level driver
+ * header.
+ *
+ * @init
+ */
+#define palInit(config) pal_lld_init(config)
+
+/**
+ * @brief Reads the physical I/O port states.
+ * @note The default implementation always return zero and computes the
+ * parameter eventual side effects.
+ *
+ * @param[in] port port identifier
+ * @return The port logical states.
+ *
+ * @api
+ */
+#if !defined(pal_lld_readport) || defined(__DOXYGEN__)
+#define palReadPort(port) ((void)(port), 0)
+#else
+#define palReadPort(port) pal_lld_readport(port)
+#endif
+
+/**
+ * @brief Reads the output latch.
+ * @details The purpose of this function is to read back the latched output
+ * value.
+ * @note The default implementation always return zero and computes the
+ * parameter eventual side effects.
+ *
+ * @param[in] port port identifier
+ * @return The latched logical states.
+ *
+ * @api
+ */
+#if !defined(pal_lld_readlatch) || defined(__DOXYGEN__)
+#define palReadLatch(port) ((void)(port), 0)
+#else
+#define palReadLatch(port) pal_lld_readlatch(port)
+#endif
+
+/**
+ * @brief Writes a bits mask on a I/O port.
+ * @note The default implementation does nothing except computing the
+ * parameters eventual side effects.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be written on the specified port
+ *
+ * @api
+ */
+#if !defined(pal_lld_writeport) || defined(__DOXYGEN__)
+#define palWritePort(port, bits) ((void)(port), (void)(bits))
+#else
+#define palWritePort(port, bits) pal_lld_writeport(port, bits)
+#endif
+
+/**
+ * @brief Sets a bits mask on a I/O port.
+ * @note The operation is not guaranteed to be atomic on all the
+ * architectures, for atomicity and/or portability reasons you may
+ * need to enclose port I/O operations between @p chSysLock() and
+ * @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be ORed on the specified port
+ *
+ * @api
+ */
+#if !defined(pal_lld_setport) || defined(__DOXYGEN__)
+#define palSetPort(port, bits) \
+ palWritePort(port, palReadLatch(port) | (bits))
+#else
+#define palSetPort(port, bits) pal_lld_setport(port, bits)
+#endif
+
+/**
+ * @brief Clears a bits mask on a I/O port.
+ * @note The operation is not guaranteed to be atomic on all the
+ * architectures, for atomicity and/or portability reasons you may
+ * need to enclose port I/O operations between @p chSysLock() and
+ * @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be cleared on the specified port
+ *
+ * @api
+ */
+#if !defined(pal_lld_clearport) || defined(__DOXYGEN__)
+#define palClearPort(port, bits) \
+ palWritePort(port, palReadLatch(port) & ~(bits))
+#else
+#define palClearPort(port, bits) pal_lld_clearport(port, bits)
+#endif
+
+/**
+ * @brief Toggles a bits mask on a I/O port.
+ * @note The operation is not guaranteed to be atomic on all the
+ * architectures, for atomicity and/or portability reasons you may
+ * need to enclose port I/O operations between @p chSysLock() and
+ * @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be XORed on the specified port
+ *
+ * @api
+ */
+#if !defined(pal_lld_toggleport) || defined(__DOXYGEN__)
+#define palTogglePort(port, bits) \
+ palWritePort(port, palReadLatch(port) ^ (bits))
+#else
+#define palTogglePort(port, bits) pal_lld_toggleport(port, bits)
+#endif
+
+/**
+ * @brief Reads a group of bits.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask, a logical AND is performed on the input
+ * data
+ * @param[in] offset group bit offset within the port
+ * @return The group logical states.
+ *
+ * @api
+ */
+#if !defined(pal_lld_readgroup) || defined(__DOXYGEN__)
+#define palReadGroup(port, mask, offset) \
+ ((palReadPort(port) >> (offset)) & (mask))
+#else
+#define palReadGroup(port, mask, offset) pal_lld_readgroup(port, mask, offset)
+#endif
+
+/**
+ * @brief Writes a group of bits.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask, a logical AND is performed on the
+ * output data
+ * @param[in] offset group bit offset within the port
+ * @param[in] bits bits to be written. Values exceeding the group
+ * width are masked.
+ *
+ * @api
+ */
+#if !defined(pal_lld_writegroup) || defined(__DOXYGEN__)
+#define palWriteGroup(port, mask, offset, bits) \
+ palWritePort(port, (palReadLatch(port) & ~((mask) << (offset))) | \
+ (((bits) & (mask)) << (offset)))
+#else
+#define palWriteGroup(port, mask, offset, bits) \
+ pal_lld_writegroup(port, mask, offset, bits)
+#endif
+
+
+/**
+ * @brief Pads group mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ * @note Programming an unknown or unsupported mode is silently ignored.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask
+ * @param[in] offset group bit offset within the port
+ * @param[in] mode group mode
+ *
+ * @api
+ */
+#if !defined(pal_lld_setgroupmode) || defined(__DOXYGEN__)
+#define palSetGroupMode(port, mask, offset, mode)
+#else
+#define palSetGroupMode(port, mask, offset, mode) \
+ pal_lld_setgroupmode(port, mask, offset, mode)
+#endif
+
+/**
+ * @brief Reads an input pad logical state.
+ * @note The default implementation not necessarily optimal. Low level
+ * drivers may optimize the function by using specific hardware
+ * or coding.
+ * @note The default implementation internally uses the @p palReadPort().
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @return The logical state.
+ * @retval PAL_LOW low logical state.
+ * @retval PAL_HIGH high logical state.
+ *
+ * @api
+ */
+#if !defined(pal_lld_readpad) || defined(__DOXYGEN__)
+#define palReadPad(port, pad) ((palReadPort(port) >> (pad)) & 1)
+#else
+#define palReadPad(port, pad) pal_lld_readpad(port, pad)
+#endif
+
+/**
+ * @brief Writes a logical state on an output pad.
+ * @note The operation is not guaranteed to be atomic on all the
+ * architectures, for atomicity and/or portability reasons you may
+ * need to enclose port I/O operations between @p chSysLock() and
+ * @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ * @note The default implementation internally uses the @p palReadLatch()
+ * and @p palWritePort().
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @param[in] bit logical value, the value must be @p PAL_LOW or
+ * @p PAL_HIGH
+ *
+ * @api
+ */
+#if !defined(pal_lld_writepad) || defined(__DOXYGEN__)
+#define palWritePad(port, pad, bit) \
+ palWritePort(port, (palReadLatch(port) & ~PAL_PORT_BIT(pad)) | \
+ (((bit) & 1) << pad))
+#else
+#define palWritePad(port, pad, bit) pal_lld_writepad(port, pad, bit)
+#endif
+
+/**
+ * @brief Sets a pad logical state to @p PAL_HIGH.
+ * @note The operation is not guaranteed to be atomic on all the
+ * architectures, for atomicity and/or portability reasons you may
+ * need to enclose port I/O operations between @p chSysLock() and
+ * @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ * @note The default implementation internally uses the @p palSetPort().
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @api
+ */
+#if !defined(pal_lld_setpad) || defined(__DOXYGEN__)
+#define palSetPad(port, pad) palSetPort(port, PAL_PORT_BIT(pad))
+#else
+#define palSetPad(port, pad) pal_lld_setpad(port, pad)
+#endif
+
+/**
+ * @brief Clears a pad logical state to @p PAL_LOW.
+ * @note The operation is not guaranteed to be atomic on all the
+ * architectures, for atomicity and/or portability reasons you may
+ * need to enclose port I/O operations between @p chSysLock() and
+ * @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ * @note The default implementation internally uses the @p palClearPort().
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @api
+ */
+#if !defined(pal_lld_clearpad) || defined(__DOXYGEN__)
+#define palClearPad(port, pad) palClearPort(port, PAL_PORT_BIT(pad))
+#else
+#define palClearPad(port, pad) pal_lld_clearpad(port, pad)
+#endif
+
+/**
+ * @brief Toggles a pad logical state.
+ * @note The operation is not guaranteed to be atomic on all the
+ * architectures, for atomicity and/or portability reasons you may
+ * need to enclose port I/O operations between @p chSysLock() and
+ * @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ * @note The default implementation internally uses the @p palTogglePort().
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @api
+ */
+#if !defined(pal_lld_togglepad) || defined(__DOXYGEN__)
+#define palTogglePad(port, pad) palTogglePort(port, PAL_PORT_BIT(pad))
+#else
+#define palTogglePad(port, pad) pal_lld_togglepad(port, pad)
+#endif
+
+/**
+ * @brief Pad mode setup.
+ * @details This function programs a pad with the specified mode.
+ * @note The default implementation not necessarily optimal. Low level
+ * drivers may optimize the function by using specific hardware
+ * or coding.
+ * @note Programming an unknown or unsupported mode is silently ignored.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @param[in] mode pad mode
+ *
+ * @api
+ */
+#if !defined(pal_lld_setpadmode) || defined(__DOXYGEN__)
+#define palSetPadMode(port, pad, mode) \
+ palSetGroupMode(port, PAL_PORT_BIT(pad), 0, mode)
+#else
+#define palSetPadMode(port, pad, mode) pal_lld_setpadmode(port, pad, mode)
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ ioportmask_t palReadBus(IOBus *bus);
+ void palWriteBus(IOBus *bus, ioportmask_t bits);
+ void palSetBusMode(IOBus *bus, iomode_t mode);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PAL_H_ */
+
+#endif /* HAL_USE_PAL */
+
+/** @} */
diff --git a/os/hal/include/pwm.h b/os/hal/include/pwm.h
new file mode 100644
index 000000000..a735cfbc2
--- /dev/null
+++ b/os/hal/include/pwm.h
@@ -0,0 +1,252 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 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 pwm.h
+ * @brief PWM Driver macros and structures.
+ *
+ * @addtogroup PWM
+ * @{
+ */
+
+#ifndef _PWM_H_
+#define _PWM_H_
+
+#if HAL_USE_PWM || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name PWM output mode macros
+ * @{
+ */
+/**
+ * @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. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ PWM_UNINIT = 0, /**< Not initialized. */
+ PWM_STOP = 1, /**< Stopped. */
+ PWM_READY = 2, /**< Ready. */
+} pwmstate_t;
+
+/**
+ * @brief Type of a structure representing a 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);
+
+#include "pwm_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name PWM duty cycle conversion
+ * @{
+ */
+/**
+ * @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)
+/** @} */
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @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.
+ * @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)
+ * @param[in] width PWM pulse width as clock pulses number
+ *
+ * @iclass
+ */
+#define pwmEnableChannelI(pwmp, channel, width) \
+ pwm_lld_enable_channel(pwmp, channel, width)
+
+/**
+ * @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 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)
+ *
+ * @iclass
+ */
+#define pwmDisableChannelI(pwmp, channel) \
+ pwm_lld_disable_channel(pwmp, channel)
+
+/**
+ * @brief Returns a PWM channel status.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
+ *
+ * @iclass
+ */
+#define pwmIsChannelEnabledI(pwmp, channel) \
+ pwm_lld_is_channel_enabled(pwmp, channel)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void pwmInit(void);
+ 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);
+ void pwmDisableChannel(PWMDriver *pwmp, pwmchannel_t channel);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_PWM */
+
+#endif /* _PWM_H_ */
+
+/** @} */
diff --git a/os/hal/include/serial.h b/os/hal/include/serial.h
new file mode 100644
index 000000000..8ea2248bd
--- /dev/null
+++ b/os/hal/include/serial.h
@@ -0,0 +1,312 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 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 serial.h
+ * @brief Serial Driver macros and structures.
+ *
+ * @addtogroup SERIAL
+ * @{
+ */
+
+#ifndef _SERIAL_H_
+#define _SERIAL_H_
+
+#if HAL_USE_SERIAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name Serial status flags
+ * @{
+ */
+#define SD_PARITY_ERROR 32 /**< @brief Parity error happened. */
+#define SD_FRAMING_ERROR 64 /**< @brief Framing error happened. */
+#define SD_OVERRUN_ERROR 128 /**< @brief Overflow happened. */
+#define SD_NOISE_ERROR 256 /**< @brief Noise on the line. */
+#define SD_BREAK_DETECTED 512 /**< @brief Break detected. */
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Serial configuration options
+ * @{
+ */
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, this is the baud rate selected for the
+ * default configuration.
+ */
+#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
+#define SERIAL_DEFAULT_BITRATE 38400
+#endif
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 16 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 16
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ SD_UNINIT = 0, /**< Not initialized. */
+ SD_STOP = 1, /**< Stopped. */
+ SD_READY = 2 /**< Ready. */
+} sdstate_t;
+
+/**
+ * @brief Structure representing a serial driver.
+ */
+typedef struct SerialDriver SerialDriver;
+
+#include "serial_lld.h"
+
+/**
+ * @brief @p SerialDriver specific methods.
+ */
+#define _serial_driver_methods \
+ _base_asynchronous_channel_methods
+
+/**
+ * @extends BaseAsynchronousChannelVMT
+ *
+ * @brief @p SerialDriver virtual methods table.
+ */
+struct SerialDriverVMT {
+ _serial_driver_methods
+};
+
+/**
+ * @extends BaseAsynchronousChannel
+ *
+ * @brief Full duplex serial driver class.
+ * @details This class extends @p BaseAsynchronousChannel by adding physical
+ * I/O queues.
+ */
+struct SerialDriver {
+ /** @brief Virtual Methods Table.*/
+ const struct SerialDriverVMT *vmt;
+ _serial_driver_data
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Direct output check on a @p SerialDriver.
+ * @note This function bypasses the indirect access to the channel and
+ * checks directly the output queue. This is faster but cannot
+ * be used to check different channels implementations.
+ *
+ * @deprecated
+ *
+ * @api
+ */
+#define sdPutWouldBlock(sdp) oqIsFullI(&(sdp)->oqueue)
+
+/**
+ * @brief Direct input check on a @p SerialDriver.
+ * @note This function bypasses the indirect access to the channel and
+ * checks directly the input queue. This is faster but cannot
+ * be used to check different channels implementations.
+ *
+ * @deprecated
+ *
+ * @api
+ */
+#define sdGetWouldBlock(sdp) iqIsEmptyI(&(sdp)->iqueue)
+
+/**
+ * @brief Direct write to a @p SerialDriver.
+ * @note This function bypasses the indirect access to the channel and
+ * writes directly on the output queue. This is faster but cannot
+ * be used to write to different channels implementations.
+ *
+ * @see chnPutTimeout()
+ *
+ * @api
+ */
+#define sdPut(sdp, b) oqPut(&(sdp)->oqueue, b)
+
+/**
+ * @brief Direct write to a @p SerialDriver with timeout specification.
+ * @note This function bypasses the indirect access to the channel and
+ * writes directly on the output queue. This is faster but cannot
+ * be used to write to different channels implementations.
+ *
+ * @see chnPutTimeout()
+ *
+ * @api
+ */
+#define sdPutTimeout(sdp, b, t) oqPutTimeout(&(sdp)->oqueue, b, t)
+
+/**
+ * @brief Direct read from a @p SerialDriver.
+ * @note This function bypasses the indirect access to the channel and
+ * reads directly from the input queue. This is faster but cannot
+ * be used to read from different channels implementations.
+ *
+ * @see chnGetTimeout()
+ *
+ * @api
+ */
+#define sdGet(sdp) iqGet(&(sdp)->iqueue)
+
+/**
+ * @brief Direct read from a @p SerialDriver with timeout specification.
+ * @note This function bypasses the indirect access to the channel and
+ * reads directly from the input queue. This is faster but cannot
+ * be used to read from different channels implementations.
+ *
+ * @see chnGetTimeout()
+ *
+ * @api
+ */
+#define sdGetTimeout(sdp, t) iqGetTimeout(&(sdp)->iqueue, t)
+
+/**
+ * @brief Direct blocking write to a @p SerialDriver.
+ * @note This function bypasses the indirect access to the channel and
+ * writes directly to the output queue. This is faster but cannot
+ * be used to write from different channels implementations.
+ *
+ * @see chnWrite()
+ *
+ * @api
+ */
+#define sdWrite(sdp, b, n) \
+ oqWriteTimeout(&(sdp)->oqueue, b, n, TIME_INFINITE)
+
+/**
+ * @brief Direct blocking write to a @p SerialDriver with timeout
+ * specification.
+ * @note This function bypasses the indirect access to the channel and
+ * writes directly to the output queue. This is faster but cannot
+ * be used to write to different channels implementations.
+ *
+ * @see chnWriteTimeout()
+ *
+ * @api
+ */
+#define sdWriteTimeout(sdp, b, n, t) \
+ oqWriteTimeout(&(sdp)->oqueue, b, n, t)
+
+/**
+ * @brief Direct non-blocking write to a @p SerialDriver.
+ * @note This function bypasses the indirect access to the channel and
+ * writes directly to the output queue. This is faster but cannot
+ * be used to write to different channels implementations.
+ *
+ * @see chnWriteTimeout()
+ *
+ * @api
+ */
+#define sdAsynchronousWrite(sdp, b, n) \
+ oqWriteTimeout(&(sdp)->oqueue, b, n, TIME_IMMEDIATE)
+
+/**
+ * @brief Direct blocking read from a @p SerialDriver.
+ * @note This function bypasses the indirect access to the channel and
+ * reads directly from the input queue. This is faster but cannot
+ * be used to read from different channels implementations.
+ *
+ * @see chnRead()
+ *
+ * @api
+ */
+#define sdRead(sdp, b, n) \
+ iqReadTimeout(&(sdp)->iqueue, b, n, TIME_INFINITE)
+
+/**
+ * @brief Direct blocking read from a @p SerialDriver with timeout
+ * specification.
+ * @note This function bypasses the indirect access to the channel and
+ * reads directly from the input queue. This is faster but cannot
+ * be used to read from different channels implementations.
+ *
+ * @see chnReadTimeout()
+ *
+ * @api
+ */
+#define sdReadTimeout(sdp, b, n, t) \
+ iqReadTimeout(&(sdp)->iqueue, b, n, t)
+
+/**
+ * @brief Direct non-blocking read from a @p SerialDriver.
+ * @note This function bypasses the indirect access to the channel and
+ * reads directly from the input queue. This is faster but cannot
+ * be used to read from different channels implementations.
+ *
+ * @see chnReadTimeout()
+ *
+ * @api
+ */
+#define sdAsynchronousRead(sdp, b, n) \
+ iqReadTimeout(&(sdp)->iqueue, b, n, TIME_IMMEDIATE)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void sdInit(void);
+ void sdObjectInit(SerialDriver *sdp, qnotify_t inotify, qnotify_t onotify);
+ void sdStart(SerialDriver *sdp, const SerialConfig *config);
+ void sdStop(SerialDriver *sdp);
+ void sdIncomingDataI(SerialDriver *sdp, uint8_t b);
+ msg_t sdRequestDataI(SerialDriver *sdp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SERIAL */
+
+#endif /* _SERIAL_H_ */
+
+/** @} */
diff --git a/os/hal/include/spi.h b/os/hal/include/spi.h
new file mode 100644
index 000000000..48182e65d
--- /dev/null
+++ b/os/hal/include/spi.h
@@ -0,0 +1,310 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 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 spi.h
+ * @brief SPI Driver macros and structures.
+ *
+ * @addtogroup SPI
+ * @{
+ */
+
+#ifndef _SPI_H_
+#define _SPI_H_
+
+#if HAL_USE_SPI || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name SPI configuration options
+ * @{
+ */
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
+#define SPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define SPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ SPI_UNINIT = 0, /**< Not initialized. */
+ SPI_STOP = 1, /**< Stopped. */
+ SPI_READY = 2, /**< Ready. */
+ SPI_ACTIVE = 3, /**< Exchanging data. */
+ SPI_COMPLETE = 4 /**< Asynchronous operation complete. */
+} spistate_t;
+
+#include "spi_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Asserts the slave select signal and prepares for transfers.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @iclass
+ */
+#define spiSelectI(spip) { \
+ spi_lld_select(spip); \
+}
+
+/**
+ * @brief Deasserts the slave select signal.
+ * @details The previously selected peripheral is unselected.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @iclass
+ */
+#define spiUnselectI(spip) { \
+ spi_lld_unselect(spip); \
+}
+
+/**
+ * @brief Ignores data on the SPI bus.
+ * @details This asynchronous function starts the transmission of a series of
+ * idle words on the SPI bus and ignores the received data.
+ * @pre A slave must have been selected using @p spiSelect() or
+ * @p spiSelectI().
+ * @post At the end of the operation the configured callback is invoked.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to be ignored
+ *
+ * @iclass
+ */
+#define spiStartIgnoreI(spip, n) { \
+ (spip)->state = SPI_ACTIVE; \
+ spi_lld_ignore(spip, n); \
+}
+
+/**
+ * @brief Exchanges data on the SPI bus.
+ * @details This asynchronous function starts a simultaneous transmit/receive
+ * operation.
+ * @pre A slave must have been selected using @p spiSelect() or
+ * @p spiSelectI().
+ * @post At the end of the operation the configured callback is invoked.
+ * @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.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to be exchanged
+ * @param[in] txbuf the pointer to the transmit buffer
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @iclass
+ */
+#define spiStartExchangeI(spip, n, txbuf, rxbuf) { \
+ (spip)->state = SPI_ACTIVE; \
+ spi_lld_exchange(spip, n, txbuf, rxbuf); \
+}
+
+/**
+ * @brief Sends data over the SPI bus.
+ * @details This asynchronous function starts a transmit operation.
+ * @pre A slave must have been selected using @p spiSelect() or
+ * @p spiSelectI().
+ * @post At the end of the operation the configured callback is invoked.
+ * @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.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ *
+ * @iclass
+ */
+#define spiStartSendI(spip, n, txbuf) { \
+ (spip)->state = SPI_ACTIVE; \
+ spi_lld_send(spip, n, txbuf); \
+}
+
+/**
+ * @brief Receives data from the SPI bus.
+ * @details This asynchronous function starts a receive operation.
+ * @pre A slave must have been selected using @p spiSelect() or
+ * @p spiSelectI().
+ * @post At the end of the operation the configured callback is invoked.
+ * @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.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to receive
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @iclass
+ */
+#define spiStartReceiveI(spip, n, rxbuf) { \
+ (spip)->state = SPI_ACTIVE; \
+ spi_lld_receive(spip, n, rxbuf); \
+}
+
+/**
+ * @brief Exchanges one frame using a polled wait.
+ * @details This synchronous function exchanges one frame using a polled
+ * synchronization method. This function is useful when exchanging
+ * small amount of data on high speed channels, usually in this
+ * situation is much more efficient just wait for completion using
+ * polling than suspending the thread waiting for an interrupt.
+ * @note This API is implemented as a macro in order to minimize latency.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] frame the data frame to send over the SPI bus
+ * @return The received data frame from the SPI bus.
+ */
+#define spiPolledExchange(spip, frame) spi_lld_polled_exchange(spip, frame)
+/** @} */
+
+/**
+ * @name Low Level driver helper macros
+ * @{
+ */
+#if SPI_USE_WAIT || defined(__DOXYGEN__)
+/**
+ * @brief Waits for operation completion.
+ * @details This function waits for the driver to complete the current
+ * operation.
+ * @pre An operation must be running while the function is invoked.
+ * @note No more than one thread can wait on a SPI driver using
+ * this function.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+#define _spi_wait_s(spip) osalThreadSuspendS(&(spip)->thread)
+
+/**
+ * @brief Wakes up the waiting thread.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+#define _spi_wakeup_isr(spip) { \
+ osalSysLockFromISR(); \
+ osalThreadResumeI(&(spip)->thread, MSG_OK); \
+ osalSysUnlockFromISR(); \
+}
+#else /* !SPI_USE_WAIT */
+#define _spi_wait_s(spip)
+#define _spi_wakeup_isr(spip)
+#endif /* !SPI_USE_WAIT */
+
+/**
+ * @brief Common ISR code.
+ * @details This code handles the portable part of the ISR code:
+ * - Callback invocation.
+ * - Waiting thread wakeup, if any.
+ * - Driver state transitions.
+ * .
+ * @note This macro is meant to be used in the low level drivers
+ * implementation only.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+#define _spi_isr_code(spip) { \
+ 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); \
+}
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void spiInit(void);
+ void spiObjectInit(SPIDriver *spip);
+ void spiStart(SPIDriver *spip, const SPIConfig *config);
+ void spiStop(SPIDriver *spip);
+ void spiSelect(SPIDriver *spip);
+ void spiUnselect(SPIDriver *spip);
+ void spiStartIgnore(SPIDriver *spip, size_t n);
+ void spiStartExchange(SPIDriver *spip, size_t n,
+ const void *txbuf, void *rxbuf);
+ void spiStartSend(SPIDriver *spip, size_t n, const void *txbuf);
+ void spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf);
+#if SPI_USE_WAIT
+ void spiIgnore(SPIDriver *spip, size_t n);
+ void spiExchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf);
+ void spiSend(SPIDriver *spip, size_t n, const void *txbuf);
+ void spiReceive(SPIDriver *spip, size_t n, void *rxbuf);
+#endif /* SPI_USE_WAIT */
+#if SPI_USE_MUTUAL_EXCLUSION
+ void spiAcquireBus(SPIDriver *spip);
+ void spiReleaseBus(SPIDriver *spip);
+#endif /* SPI_USE_MUTUAL_EXCLUSION */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SPI */
+
+#endif /* _SPI_H_ */
+
+/** @} */
diff --git a/os/hal/include/st.h b/os/hal/include/st.h
new file mode 100644
index 000000000..276ab2649
--- /dev/null
+++ b/os/hal/include/st.h
@@ -0,0 +1,72 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 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 st.h
+ * @brief ST Driver macros and structures.
+ *
+ * @addtogroup ST
+ * @{
+ */
+
+#ifndef _ST_H_
+#define _ST_H_
+
+#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+#include "st_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void stInit(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OSAL_ST_MODE != OSAL_ST_MODE_NONE */
+
+#endif /* _ST_H_ */
+
+/** @} */