From 27654c1bb64c74f7b5b5516945b24e1793ed8c12 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 11 Nov 2010 18:51:10 +0000 Subject: STM8L platform support (not tested yet). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2347 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM8L/hal_lld.c | 4 +- os/hal/platforms/STM8L/hal_lld.h | 1 - os/hal/platforms/STM8L/pal_lld.c | 110 +++++++++++++++ os/hal/platforms/STM8L/pal_lld.h | 231 +++++++++++++++++++++++++++++++ os/hal/platforms/STM8L/serial_lld.c | 230 +++++++++++++++++++++++++++++++ os/hal/platforms/STM8L/serial_lld.h | 266 ++++++++++++++++++++++++++++++++++++ os/hal/platforms/STM8L/shared_isr.c | 188 +++++++++++++++++++++++++ 7 files changed, 1027 insertions(+), 3 deletions(-) create mode 100644 os/hal/platforms/STM8L/pal_lld.c create mode 100644 os/hal/platforms/STM8L/pal_lld.h create mode 100644 os/hal/platforms/STM8L/serial_lld.c create mode 100644 os/hal/platforms/STM8L/serial_lld.h create mode 100644 os/hal/platforms/STM8L/shared_isr.c (limited to 'os/hal/platforms/STM8L') diff --git a/os/hal/platforms/STM8L/hal_lld.c b/os/hal/platforms/STM8L/hal_lld.c index 8c0f645a6..881a09fdd 100644 --- a/os/hal/platforms/STM8L/hal_lld.c +++ b/os/hal/platforms/STM8L/hal_lld.c @@ -39,7 +39,7 @@ /** * @brief PAL setup. * @details Digital I/O ports static configuration as defined in @p board.h. - *//* + */ ROMCONST PALConfig pal_default_config = { { @@ -55,7 +55,7 @@ ROMCONST PALConfig pal_default_config = {VAL_GPIOIODR, 0, VAL_GPIOIDDR, VAL_GPIOICR1, VAL_GPIOICR2}, #endif } -};*/ +}; /*===========================================================================*/ /* Driver local functions. */ diff --git a/os/hal/platforms/STM8L/hal_lld.h b/os/hal/platforms/STM8L/hal_lld.h index 891f2650b..8d658e6dc 100644 --- a/os/hal/platforms/STM8L/hal_lld.h +++ b/os/hal/platforms/STM8L/hal_lld.h @@ -16,7 +16,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ - /** * @file STM8L/hal_lld.h * @brief STM8L HAL subsystem low level driver source. diff --git a/os/hal/platforms/STM8L/pal_lld.c b/os/hal/platforms/STM8L/pal_lld.c new file mode 100644 index 000000000..a91f380a4 --- /dev/null +++ b/os/hal/platforms/STM8L/pal_lld.c @@ -0,0 +1,110 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM8L/pal_lld.c + * @brief STM8L GPIO low level driver code. + * + * @addtogroup PAL + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_PAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Pads mode setup. + * @details This function programs a pads group belonging to the same port + * with the specified mode. + * @note This function is not meant to be invoked directly by the + * application code. + * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output at 2MHz. + * + * @param[in] port the port identifier + * @param[in] mask the group mask + * @param[in] mode the mode + * + * @notapi + */ +void _pal_lld_setgroupmode(ioportid_t port, + ioportmask_t mask, + uint_fast8_t mode) { + + switch (mode & PAL_MODE_MASK) { + case PAL_MODE_RESET: + case PAL_MODE_INPUT_PULLUP: + port->DDR &= ~mask; + port->CR1 |= mask; + port->CR2 &= ~mask; + break; + case PAL_MODE_INPUT: + case PAL_MODE_INPUT_ANALOG: + port->DDR &= ~mask; + port->CR1 &= ~mask; + port->CR2 &= ~mask; + break; + case PAL_MODE_UNCONNECTED: + case PAL_MODE_OUTPUT_PUSHPULL_SLOW: + port->DDR |= mask; + port->CR1 |= mask; + port->CR2 &= ~mask; + break; + case PAL_MODE_OUTPUT_PUSHPULL: + port->DDR |= mask; + port->CR1 |= mask; + port->CR2 |= mask; + break; + case PAL_MODE_OUTPUT_OPENDRAIN_SLOW: + port->DDR |= mask; + port->CR1 &= ~mask; + port->CR2 &= ~mask; + break; + case PAL_MODE_OUTPUT_OPENDRAIN: + port->DDR |= mask; + port->CR1 &= ~mask; + port->CR2 |= mask; + break; + } +} + +#endif /* HAL_USE_PAL */ + +/** @} */ diff --git a/os/hal/platforms/STM8L/pal_lld.h b/os/hal/platforms/STM8L/pal_lld.h new file mode 100644 index 000000000..64650adaf --- /dev/null +++ b/os/hal/platforms/STM8L/pal_lld.h @@ -0,0 +1,231 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM8L/pal_lld.h + * @brief STM8L GPIO low level driver header. + * + * @addtogroup PAL + * @{ + */ + +#ifndef _PAL_LLD_H_ +#define _PAL_LLD_H_ + +#if HAL_USE_PAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Unsupported modes and specific modes */ +/*===========================================================================*/ + +#undef PAL_MODE_INPUT_PULLDOWN + +/** + * @brief STM8L specific alternate push-pull slow output mode. + */ +#define PAL_MODE_OUTPUT_PUSHPULL_SLOW 16 + +/** + * @brief STM8L specific alternate open-drain slow output mode. + */ +#define PAL_MODE_OUTPUT_OPENDRAIN_SLOW 17 + +/*===========================================================================*/ +/* I/O Ports Types and constants. */ +/*===========================================================================*/ + +/** + * @brief Generic I/O ports static initializer. + * @details An instance of this structure must be passed to @p palInit() at + * system startup time in order to initialized the digital I/O + * subsystem. This represents only the initial setup, specific pads + * or whole ports can be reprogrammed at later time. + */ +typedef struct { +#if defined(STM8L15X_MD) || defined(__DOXYGEN__) + GPIO_TypeDef P[7]; +#elif defined(STM8L15X_MDP) || defined(STM8L15X_HD) + GPIO_TypeDef P[9]; +#endif +} PALConfig; + +/** + * @brief Width, in bits, of an I/O port. + */ +#define PAL_IOPORTS_WIDTH 8 + +/** + * @brief Whole port mask. + * @brief This macro specifies all the valid bits into a port. + */ +#define PAL_WHOLE_PORT ((ioportmask_t)0xFF) + +/** + * @brief Digital I/O port sized unsigned type. + */ +typedef uint8_t ioportmask_t; + +/** + * @brief Port Identifier. + */ +typedef GPIO_TypeDef *ioportid_t; + +/*===========================================================================*/ +/* I/O Ports Identifiers. */ +/*===========================================================================*/ + +/** + * @brief GPIO ports as a whole. + */ +#define IOPORTS ((PALConfig *)0x5000) + +/** + * @brief GPIO port A identifier. + */ +#define IOPORT1 GPIOA + +/** + * @brief GPIO port B identifier. + */ +#define IOPORT2 GPIOB + +/** + * @brief GPIO port C identifier. + */ +#define IOPORT3 GPIOC + +/** + * @brief GPIO port D identifier. + */ +#define IOPORT4 GPIOD + +/** + * @brief GPIO port E identifier. + */ +#define IOPORT5 GPIOE + +/** + * @brief GPIO port F identifier. + */ +#define IOPORT6 GPIOF + +/** + * @brief GPIO port G identifier. + */ +#define IOPORT7 GPIOG + +#if defined(STM8L15X_MDP) || defined(STM8L15X_HD) +/** + * @brief GPIO port H identifier. + */ +#define IOPORT8 GPIOH + +/** + * @brief GPIO port I identifier. + */ +#define IOPORT9 GPIOI +#endif /* defined(STM8L15X_MDP) || defined(STM8L15X_HD) */ + +/*===========================================================================*/ +/* Implementation, some of the following macros could be implemented as */ +/* functions, if so please put them in pal_lld.c. */ +/*===========================================================================*/ + +/** + * @brief Low level PAL subsystem initialization. + * + * @param[in] config architecture-dependent ports configuration + * + * @notapi + */ +#define pal_lld_init(config) *IOPORTS = *(config) + +/** + * @brief Reads the physical I/O port states. + * @note This function is not meant to be invoked directly by the + * application code. + * + * @param[in] port port identifier + * @return The port bits. + * + * @notapi + */ +#define pal_lld_readport(port) ((port)->IDR) + +/** + * @brief Reads the output latch. + * @details The purpose of this function is to read back the latched output + * value. + * @note This function is not meant to be invoked directly by the + * application code. + * + * @param[in] port port identifier + * @return The latched logical states. + * + * @notapi + */ +#define pal_lld_readlatch(port) ((port)->ODR) + +/** + * @brief Writes a bits mask on a I/O port. + * @note This function is not meant to be invoked directly by the + * application code. + * + * @param[in] port port identifier + * @param[in] bits bits to be written on the specified port + * + * @notapi + */ +#define pal_lld_writeport(port, bits) ((port)->ODR = (bits)) + + +/** + * @brief Pads group mode setup. + * @details This function programs a pads group belonging to the same port + * with the specified mode. + * @note This function is not meant to be invoked directly by the + * application code. + * @note Programming an unknown or unsupported mode is silently ignored. + * + * @param[in] port port identifier + * @param[in] mask group mask + * @param[in] mode group mode + * + * @notapi + */ +#define pal_lld_setgroupmode(port, mask, mode) \ + _pal_lld_setgroupmode(port, mask, mode) + +extern ROMCONST PALConfig pal_default_config; + +#ifdef __cplusplus +extern "C" { +#endif + void _pal_lld_setgroupmode(ioportid_t port, + ioportmask_t mask, + uint_fast8_t mode); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_PAL */ + +#endif /* _PAL_LLD_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM8L/serial_lld.c b/os/hal/platforms/STM8L/serial_lld.c new file mode 100644 index 000000000..dcb99643a --- /dev/null +++ b/os/hal/platforms/STM8L/serial_lld.c @@ -0,0 +1,230 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM8L/serial_lld.c + * @brief STM8L low level serial driver code. + * + * @addtogroup SERIAL + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_SERIAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief USART1 serial driver identifier. + */ +#if STM8L_SERIAL_USE_USART1 || defined(__DOXYGEN__) +SerialDriver SD1; +#endif + +/** + * @brief USART2 serial driver identifier. + */ +#if STM8L_SERIAL_USE_USART2 || defined(__DOXYGEN__) +SerialDriver SD2; +#endif + +/** + * @brief USART3 serial driver identifier. + */ +#if STM8L_SERIAL_USE_USART3 || defined(__DOXYGEN__) +SerialDriver SD3; +#endif + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/** + * @brief Driver default configuration. + */ +static ROMCONST SerialConfig default_config = { + BBR(SERIAL_DEFAULT_BITRATE), + SD_MODE_PARITY_NONE | SD_MODE_STOP_1 +}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief USART initialization. + * + * @param[in] config architecture-dependent serial driver configuration + * @param[in] sdp pointer to a @p SerialDriver object + */ +static void usart_init(SerialDriver *sdp, const SerialConfig *config) { + USART_TypeDef *u = sdp->usart; + + u->BRR2 = (uint8_t)(((uint8_t)(config->sc_brr >> 8) & (uint8_t)0xF0) | + ((uint8_t)config->sc_brr & (uint8_t)0x0F)); + u->BRR1 = (uint8_t)(config->sc_brr >> 4); + u->CR1 = (uint8_t)(config->sc_mode & SD_MODE_PARITY); + u->CR2 = USART_CR2_RIEN | USART_CR2_TEN | USART_CR2_REN; + u->CR3 = (uint8_t)(config->sc_mode & SD_MODE_STOP); + u->CR4 = 0; + u->CR5 = 0; + u->PSCR = 1; + (void)u->SR; + (void)u->DR; +} + +/** + * @brief USART de-initialization. + * + * @param[in] sdp pointer to a @p SerialDriver object + */ +static void usart_deinit(SerialDriver *sdp) { + USART_TypeDef *u = sdp->usart; + + u->CR1 = USART_CR1_USARTD; + u->CR2 = 0; + u->CR3 = 0; + u->CR4 = 0; + u->CR5 = 0; + u->PSCR = 0; +} + +#if STM8L_SERIAL_USE_USART1 || defined(__DOXYGEN__) +static void notify1(void) { + + USART1->CR2 |= USART_CR2_TIEN; +} +#endif /* STM8L_SERIAL_USE_USART1 */ + +#if STM8L_SERIAL_USE_USART2 || defined(__DOXYGEN__) +static void notify2(void) { + + USART2->CR2 |= USART_CR2_TIEN; +} +#endif /* STM8L_SERIAL_USE_USART1 */ + +#if STM8L_SERIAL_USE_USART3 || defined(__DOXYGEN__) +static void notify3(void) { + + USART3->CR2 |= USART_CR2_TIEN; +} +#endif /* STM8L_SERIAL_USE_USART3 */ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/* See in serial_lld.h.*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Error handling routine. + * + * @param[in] sdp pointer to a @p SerialDriver object + * @param[in] sr USART SR register value + * + * @notapi + */ +void sd_lld_set_error(SerialDriver *sdp, uint8_t sr) { + sdflags_t sts = 0; + + if (sr & USART_SR_OR) + sts |= SD_OVERRUN_ERROR; + if (sr & USART_SR_NF) + sts |= SD_NOISE_ERROR; + if (sr & USART_SR_FE) + sts |= SD_FRAMING_ERROR; + if (sr & USART_SR_PE) + sts |= SD_PARITY_ERROR; + chSysLockFromIsr(); + sdAddFlagsI(sdp, sts); + chSysUnlockFromIsr(); +} + +/** + * @brief Low level serial driver initialization. + * + * @notapi + */ +void sd_lld_init(void) { + +#if STM8L_SERIAL_USE_USART1 + sdObjectInit(&SD1, NULL, notify1); + CLK->PCKENR1 |= CLK_PCKENR1_USART1; /* PCKEN12, clock source. */ + USART1->CR1 = USART_CR1_USARTD; /* USARTD (low power). */ + SD1.usart = USART1; +#endif + +#if STM8L_SERIAL_USE_USART2 + sdObjectInit(&SD2, NULL, notify2); + CLK->PCKENR1 |= CLK_PCKENR1_USART2; /* PCKEN13, clock source. */ + USART2->CR1 = USART2_CR1_USARTD; /* USARTD (low power). */ + SD1.usart = USART2; +#endif + +#if STM8L_SERIAL_USE_USART3 + sdObjectInit(&SD3, NULL, notify3); + CLK->PCKENR1 |= CLK_PCKENR1_USART3; /* PCKEN13, clock source. */ + USART3->CR1 = USART3_CR1_USARTD; /* USARTD (low power). */ + SD1.usart = USART3; +#endif +} + +/** + * @brief Low level serial driver configuration and (re)start. + * + * @param[in] sdp pointer to a @p SerialDriver object + * @param[in] config the architecture-dependent serial driver configuration. + * If this parameter is set to @p NULL then a default + * configuration is used. + * + * @notapi + */ +void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) { + + if (config == NULL) + config = &default_config; + + usart_init(sdp, config); +} + +/** + * @brief Low level serial driver stop. + * @details De-initializes the USART, stops the associated clock, resets the + * interrupt vector. + * + * @param[in] sdp pointer to a @p SerialDriver object + * + * @notapi + */ +void sd_lld_stop(SerialDriver *sdp) { + + usart_deinit(sdp); +} + +#endif /* HAL_USE_SERIAL */ + +/** @} */ diff --git a/os/hal/platforms/STM8L/serial_lld.h b/os/hal/platforms/STM8L/serial_lld.h new file mode 100644 index 000000000..ac829cf1e --- /dev/null +++ b/os/hal/platforms/STM8L/serial_lld.h @@ -0,0 +1,266 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM8L/serial_lld.h + * @brief STM8L low level serial driver header. + * + * @addtogroup SERIAL + * @{ + */ + +#ifndef _SERIAL_LLD_H_ +#define _SERIAL_LLD_H_ + +#if HAL_USE_SERIAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +#define SD_MODE_PARITY 0x07 /**< @brief Parity field mask. */ +#define SD_MODE_PARITY_NONE 0x00 /**< @brief No parity. */ +#define SD_MODE_PARITY_EVEN 0x05 /**< @brief Even parity. */ +#define SD_MODE_PARITY_ODD 0x07 /**< @brief Odd parity. */ + +#define SD_MODE_STOP 0x30 /**< @brief Stop bits mask. */ +#define SD_MODE_STOP_1 0x00 /**< @brief One stop bit. */ +#define SD_MODE_STOP_2 0x20 /**< @brief Two stop bits. */ +#define SD_MODE_STOP_1P5 0x30 /**< @brief 1.5 stop bits. */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief USART1 driver enable switch. + * @details If set to @p TRUE the support for USART1 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM8L_SERIAL_USE_USART1) || defined(__DOXYGEN__) +#define STM8L_SERIAL_USE_USART1 TRUE +#endif + +/** + * @brief USART2 driver enable switch. + * @details If set to @p TRUE the support for USART3 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM8L_SERIAL_USE_USART2) || defined(__DOXYGEN__) +#define STM8L_SERIAL_USE_USART2 TRUE +#endif + +/** + * @brief USART3 driver enable switch. + * @details If set to @p TRUE the support for USART3 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM8L_SERIAL_USE_USART3) || defined(__DOXYGEN__) +#define STM8L_SERIAL_USE_USART3 TRUE +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if defined(STM8L15X_MD) && \ + (STM8L_SERIAL_USE_USART2 || STM8L_SERIAL_USE_USART3) +#error "STM8L15X_MD devices do not have USART2 and USART3" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Serial Driver condition flags type. + */ +typedef uint8_t sdflags_t; + +/** + * @brief Generic Serial Driver configuration structure. + * @details An instance of this structure must be passed to @p sdStart() + * in order to configure and start a serial driver operations. + * @note This structure content is architecture dependent, each driver + * implementation defines its own version and the custom static + * initializers. + */ +typedef struct { + /** + * @brief Bit rate register. + */ + uint16_t sc_brr; + /** + * @brief Mode flags. + */ + uint8_t sc_mode; +} SerialConfig; + +/** + * @brief @p SerialDriver specific data. + */ +#define _serial_driver_data \ + _base_asynchronous_channel_data \ + /* Driver state.*/ \ + sdstate_t state; \ + /* Input queue.*/ \ + InputQueue iqueue; \ + /* Output queue.*/ \ + OutputQueue oqueue; \ + /* Status Change @p EventSource.*/ \ + EventSource sevent; \ + /* I/O driver status flags.*/ \ + sdflags_t flags; \ + /* Input circular buffer.*/ \ + uint8_t ib[SERIAL_BUFFERS_SIZE]; \ + /* Output circular buffer.*/ \ + uint8_t ob[SERIAL_BUFFERS_SIZE]; \ + /* End of the mandatory fields.*/ \ + USART_TypeDef *usart; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Macro for baud rate computation. + * @note Make sure the final baud rate is within tolerance. + */ +#define BBR(b) (SYSCLK / (b)) + +#if STM8L_SERIAL_USE_USART1 || defined(__DOXYGEN__) +/** + * @brief USART1 RX interrupt handler segment. + */ +#define _USART1_RECEIVE_ISR() { \ + uint8_t sr = USART1->SR; \ + if (sr & (USART_SR_RXNE | USART_SR_OR | USART_SR_NF | \ + USART_SR_FE | USART_SR_PE)) { \ + if (sr & (USART_SR_OR | USART_SR_NF | USART_SR_FE | USART_SR_PE)) \ + sd_lld_set_error(&SD1, sr); \ + chSysLockFromIsr(); \ + sdIncomingDataI(&SD1, USART1->DR); \ + chSysUnlockFromIsr(); \ + } \ +} + +#define _USART1_TRANSMIT_ISR() { \ + if (USART1->SR & USART_SR_TXE) { \ + msg_t b; \ + chSysLockFromIsr(); \ + b = sdRequestDataI(&SD1); \ + chSysUnlockFromIsr(); \ + if (b < Q_OK) \ + USART1->CR2 &= (uint8_t)~USART_CR2_TIEN; \ + else \ + USART1->DR = (uint8_t)b; \ + } \ +} +#endif /* STM8L_SERIAL_USE_USART1 */ + +#if STM8L_SERIAL_USE_USART2 || defined(__DOXYGEN__) +/** + * @brief USART1 RX interrupt handler segment. + */ +#define _USART2_RECEIVE_ISR() { \ + uint8_t sr = USART2->SR; \ + if (sr & (USART_SR_RXNE | USART_SR_OR | USART_SR_NF | \ + USART_SR_FE | USART_SR_PE)) { \ + if (sr & (USART_SR_OR | USART_SR_NF | USART_SR_FE | USART_SR_PE)) \ + sd_lld_set_error(&SD2, sr); \ + chSysLockFromIsr(); \ + sdIncomingDataI(&SD2, USART2->DR); \ + chSysUnlockFromIsr(); \ + } \ +} + +#define _USART2_TRANSMIT_ISR() { \ + if (USART2->SR & USART_SR_TXE) { \ + msg_t b; \ + chSysLockFromIsr(); \ + b = sdRequestDataI(&SD2); \ + chSysUnlockFromIsr(); \ + if (b < Q_OK) \ + USART2->CR2 &= (uint8_t)~USART_CR2_TIEN; \ + else \ + USART2->DR = (uint8_t)b; \ + } \ +} +#endif /* STM8L_SERIAL_USE_USART2 */ + +#if STM8L_SERIAL_USE_USART3 || defined(__DOXYGEN__) +/** + * @brief USART1 RX interrupt handler segment. + */ +#define _USART3_RECEIVE_ISR() { \ + uint8_t sr = USART3->SR; \ + if (sr & (USART_SR_RXNE | USART_SR_OR | USART_SR_NF | \ + USART_SR_FE | USART_SR_PE)) { \ + if (sr & (USART_SR_OR | USART_SR_NF | USART_SR_FE | USART_SR_PE)) \ + sd_lld_set_error(&SD3, sr); \ + chSysLockFromIsr(); \ + sdIncomingDataI(&SD3, USART3->DR); \ + chSysUnlockFromIsr(); \ + } \ +} + +#define _USART3_TRANSMIT_ISR() { \ + if (USART3->SR & USART_SR_TXE) { \ + msg_t b; \ + chSysLockFromIsr(); \ + b = sdRequestDataI(&SD3); \ + chSysUnlockFromIsr(); \ + if (b < Q_OK) \ + USART3->CR2 &= (uint8_t)~USART_CR2_TIEN; \ + else \ + USART3->DR = (uint8_t)b; \ + } \ +} +#endif /* STM8L_SERIAL_USE_USART3 */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM8L_SERIAL_USE_USART1 && !defined(__DOXYGEN__) +extern SerialDriver SD1; +#endif +#if STM8L_SERIAL_USE_USART2 && !defined(__DOXYGEN__) +extern SerialDriver SD2; +#endif +#if STM8L_SERIAL_USE_USART3 && !defined(__DOXYGEN__) +extern SerialDriver SD3; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void sd_lld_init(void); + void sd_lld_start(SerialDriver *sdp, const SerialConfig *config); + void sd_lld_stop(SerialDriver *sdp); + void sd_lld_set_error(SerialDriver *sdp, uint8_t sr); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_SERIAL */ + +#endif /* _SERIAL_LLD_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM8L/shared_isr.c b/os/hal/platforms/STM8L/shared_isr.c new file mode 100644 index 000000000..279c74865 --- /dev/null +++ b/os/hal/platforms/STM8L/shared_isr.c @@ -0,0 +1,188 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM8L/shared_isr.c + * @brief STM8L shared interrupt code source. + * @details The STM8L shares some interrupt handlers among several sources. + * This module includes all the interrupt handlers that are + * used by more than one peripheral. + * + * @addtogroup HAL + * @{ + */ + +#include "ch.h" +#include "hal.h" + +/* This inclusion allows user ISR to be added to the HAL.*/ +#if defined(_USER_ISR_) +#include "user_isr.h" +#endif + +#if defined(_TIM2_UPDATE_ISR) || defined(_USART2_TRANSMIT_ISR) || \ + defined(__DOXYGEN__) +/** + * @brief IRQ 19 service routine. + * @details This handler is shared between the following sources: + * - TIM2 update/overflow/trigger/break. + * - USART2 transmit. + * + * @isr + */ +CH_IRQ_HANDLER(19) { + CH_IRQ_PROLOGUE(); + +#if defined(_TIM2_UPDATE_ISR) + _TIM2_UPDATE_ISR(); +#endif +#if defined(_USART2_TRANSMIT_ISR) + _USART2_TRANSMIT_ISR(); +#endif + + CH_IRQ_EPILOGUE(); +} +#endif /* defined(_TIM2_UPDATE_ISR) || defined(_USART2_TRANSMIT_ISR) */ + +#if defined(_TIM2_COMPARE_ISR) || defined(_USART2_RECEIVE_ISR) || \ + defined(__DOXYGEN__) +/** + * @brief IRQ 20 service routine. + * @details This handler is shared between the following sources: + * - TIM2 compare/capture + * - USART2 receive. + * . + * + * @isr + */ +CH_IRQ_HANDLER(20) { + CH_IRQ_PROLOGUE(); + +#if defined(_TIM2_COMPARE_ISR) + _TIM2_COMPARE_ISR(); +#endif +#if defined(_USART2_RECEIVE_ISR) + _USART2_RECEIVE_ISR(); +#endif + + CH_IRQ_EPILOGUE(); +} +#endif /* defined(_TIM2_COMPARE_ISR) || defined(_USART2_RECEIVE_ISR) */ + +#if defined(_TIM3_UPDATE_ISR) || defined(_USART3_TRANSMIT_ISR) || \ + defined(__DOXYGEN__) +/** + * @brief IRQ 21 service routine. + * @details This handler is shared between the following sources: + * - TIM3 update/overflow/trigger/break. + * - USART3 transmit. + * . + * + * @isr + */ +CH_IRQ_HANDLER(21) { + CH_IRQ_PROLOGUE(); + +#if defined(_TIM3_UPDATE_ISR) + _TIM3_UPDATE_ISR(); +#endif +#if defined(_USART3_TRANSMIT_ISR) + _USART3_TRANSMIT_ISR(); +#endif + + CH_IRQ_EPILOGUE(); +} +#endif /* defined(_TIM3_UPDATE_ISR) || defined(_USART3_TRANSMIT_ISR) */ + +#if defined(_TIM3_COMPARE_ISR) || defined(_USART3_RECEIVE_ISR) || \ + defined(__DOXYGEN__) +/** + * @brief IRQ 22 service routine. + * @details This handler is shared between the following sources: + * - TIM3 compare/capture + * - USART3 receive. + * . + * + * @isr + */ +CH_IRQ_HANDLER(22) { + CH_IRQ_PROLOGUE(); + +#if defined(_TIM3_COMPARE_ISR) + _TIM3_COMPARE_ISR(); +#endif +#if defined(_USART3_RECEIVE_ISR) + _USART3_RECEIVE_ISR(); +#endif + + CH_IRQ_EPILOGUE(); +} +#endif /* defined(_TIM3_COMPARE_ISR) || defined(_USART3_RECEIVE_ISR) */ + +#if defined(_TIM5_UPDATE_ISR) || defined(_USART1_TRANSMIT_ISR) || \ + defined(__DOXYGEN__) +/** + * @brief IRQ 27 service routine. + * @details This handler is shared between the following sources: + * - TIM5 update/overflow/trigger/break. + * - USART1 transmit. + * . + * + * @isr + */ +CH_IRQ_HANDLER(27) { + CH_IRQ_PROLOGUE(); + +#if defined(_TIM5_UPDATE_ISR) + _TIM5_UPDATE_ISR(); +#endif +#if defined(_USART1_TRANSMIT_ISR) + _USART1_TRANSMIT_ISR(); +#endif + + CH_IRQ_EPILOGUE(); +} +#endif /* defined(_TIM5_UPDATE_ISR) || defined(_USART1_TRANSMIT_ISR) */ + +#if defined(_TIM5_COMPARE_ISR) || defined(_USART1_RECEIVE_ISR) || \ + defined(__DOXYGEN__) +/** + * @brief IRQ 28 service routine. + * @details This handler is shared between the following sources: + * - TIM5 compare/capture + * - USART1 receive. + * . + * + * @isr + */ +CH_IRQ_HANDLER(28) { + CH_IRQ_PROLOGUE(); + +#if defined(_TIM5_COMPARE_ISR) + _TIM5_COMPARE_ISR(); +#endif +#if defined(_USART1_RECEIVE_ISR) + _USART1_RECEIVE_ISR(); +#endif + + CH_IRQ_EPILOGUE(); +} +#endif /* defined(_TIM5_COMPARE_ISR) || defined(_USART1_RECEIVE_ISR) */ + +/** @} */ -- cgit v1.2.3