git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1088 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
8ce831d013
commit
eba4712765
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file STM32F103/pal_lld.c
|
||||
* @brief STM32 GPIO low level driver code
|
||||
* @addtogroup STM32F103_PAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <ch.h>
|
||||
#include <pal.h>
|
||||
|
||||
#if defined(STM32F10X_LD)
|
||||
#define APB2_RST_MASK (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | \
|
||||
RCC_APB2RSTR_IOPCRST | RCC_APB2RSTR_IOPDRST | \
|
||||
RCC_APB2RSTR_AFIORST)
|
||||
#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
|
||||
RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
|
||||
RCC_APB2ENR_AFIOEN)
|
||||
#elif defined(STM32F10X_HD)
|
||||
#define APB2_RST_MASK (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | \
|
||||
RCC_APB2RSTR_IOPCRST | RCC_APB2RSTR_IOPDRST | \
|
||||
RCC_APB2RSTR_IOPERST | RCC_APB2RSTR_IOPFRST | \
|
||||
RCC_APB2RSTR_IOPGRST | RCC_APB2RSTR_AFIORST);
|
||||
#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
|
||||
RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
|
||||
RCC_APB2ENR_IOPEEN | RCC_APB2ENR_IOPFEN | \
|
||||
RCC_APB2ENR_IOPGEN | RCC_APB2ENR_AFIOEN)
|
||||
#else
|
||||
/* Defaults on Medium Density devices.*/
|
||||
#define APB2_RST_MASK (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | \
|
||||
RCC_APB2RSTR_IOPCRST | RCC_APB2RSTR_IOPDRST | \
|
||||
RCC_APB2RSTR_IOPERST | RCC_APB2RSTR_AFIORST);
|
||||
#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
|
||||
RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
|
||||
RCC_APB2ENR_IOPEEN | RCC_APB2ENR_AFIOEN)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief STM32 I/O ports configuration.
|
||||
* @details Ports A-D(E, F, G) clocks enabled, AFIO clock enabled.
|
||||
*
|
||||
* @param[in] config the STM32 ports configuration
|
||||
*/
|
||||
void _pal_lld_init(const STM32GPIOConfig *config) {
|
||||
|
||||
/*
|
||||
* Enables the GPIO related clocks.
|
||||
*/
|
||||
RCC->APB2ENR |= APB2_EN_MASK;
|
||||
|
||||
/*
|
||||
* Resets the GPIO ports and AFIO.
|
||||
*/
|
||||
RCC->APB2RSTR = APB2_RST_MASK;
|
||||
RCC->APB2RSTR = 0;
|
||||
|
||||
IOPORT_A->ODR = config->PAData.odr;
|
||||
IOPORT_A->CRH = config->PAData.crh;
|
||||
IOPORT_A->CRL = config->PAData.crl;
|
||||
IOPORT_B->ODR = config->PBData.odr;
|
||||
IOPORT_B->CRH = config->PBData.crh;
|
||||
IOPORT_B->CRL = config->PBData.crl;
|
||||
IOPORT_C->ODR = config->PCData.odr;
|
||||
IOPORT_C->CRH = config->PCData.crh;
|
||||
IOPORT_C->CRL = config->PCData.crl;
|
||||
IOPORT_D->ODR = config->PDData.odr;
|
||||
IOPORT_D->CRH = config->PDData.crh;
|
||||
IOPORT_D->CRL = config->PDData.crl;
|
||||
#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
|
||||
IOPORT_E->ODR = config->PEData.odr;
|
||||
IOPORT_E->CRH = config->PEData.crh;
|
||||
IOPORT_E->CRL = config->PEData.crl;
|
||||
#endif
|
||||
#if defined(STM32F10X_HD) || defined(__DOXYGEN__)
|
||||
IOPORT_F->ODR = config->PFData.odr;
|
||||
IOPORT_F->CRH = config->PFData.crh;
|
||||
IOPORT_F->CRL = config->PFData.crl;
|
||||
IOPORT_G->ODR = config->PGData.odr;
|
||||
IOPORT_G->CRH = config->PGData.crh;
|
||||
IOPORT_G->CRL = config->PGData.crl;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pads mode setup.
|
||||
* @details This function programs a pads group belonging to the same port
|
||||
* with the specified mode.
|
||||
*
|
||||
* @param[in] port the port identifier
|
||||
* @param[in] mask the group mask
|
||||
* @param[in] mode the mode
|
||||
*
|
||||
* @note This function is not meant to be invoked directly by the application
|
||||
* code.
|
||||
* @note @p PAL_MODE_UNCONNECTED is implemented as push pull output at 2MHz.
|
||||
* @note Writing on pads programmed as pull-up or pull-down has the side
|
||||
* effect to modify the resistor setting because the output latched data
|
||||
* is used for the resistor selection.
|
||||
*/
|
||||
void _pal_lld_setgroupmode(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
uint_fast8_t mode) {
|
||||
static const uint8_t cfgtab[] = {
|
||||
4, /* PAL_MODE_RESET, implemented as input.*/
|
||||
2, /* PAL_MODE_UNCONNECTED, implemented as push pull output 2MHz.*/
|
||||
4, /* PAL_MODE_INPUT */
|
||||
8, /* PAL_MODE_INPUT_PULLUP */
|
||||
8, /* PAL_MODE_INPUT_PULLDOWN */
|
||||
3, /* PAL_MODE_OUTPUT_PUSHPULL, 50MHz.*/
|
||||
7, /* PAL_MODE_OUTPUT_OPENDRAIN, 50MHz.*/
|
||||
};
|
||||
uint32_t mh, ml, crh, crl, cfg;
|
||||
unsigned i;
|
||||
|
||||
if (mode == PAL_MODE_INPUT_PULLUP)
|
||||
port->BSRR = mask;
|
||||
else if (mode == PAL_MODE_INPUT_PULLDOWN)
|
||||
port->BRR = mask;
|
||||
cfg = cfgtab[mode];
|
||||
mh = ml = crh = crl = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
ml <<= 4;
|
||||
mh <<= 4;
|
||||
crl <<= 4;
|
||||
crh <<= 4;
|
||||
if ((mask & 1) == 0)
|
||||
ml |= 0xf;
|
||||
else
|
||||
crl |= cfg;
|
||||
if ((mask & 0x10000) == 0)
|
||||
mh |= 0xf;
|
||||
else
|
||||
crh |= cfg;
|
||||
mask >>= 1;
|
||||
}
|
||||
port->CRH = (port->CRH & mh) | crh;
|
||||
port->CRL = (port->CRL & ml) | crl;
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,307 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file STM32F103/pal_lld.h
|
||||
* @brief STM32 GPIO low level driver header
|
||||
* @addtogroup STM32F103_PAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _PAL_LLD_H_
|
||||
#define _PAL_LLD_H_
|
||||
|
||||
/*
|
||||
* Tricks required to make the TRUE/FALSE declaration inside the library
|
||||
* compatible.
|
||||
*/
|
||||
#ifndef __STM32F10x_H
|
||||
#undef FALSE
|
||||
#undef TRUE
|
||||
#include <stm32f10x.h>
|
||||
#define FALSE 0
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I/O Ports Types and constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief GPIO port setup info.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Initial value for ODR register.*/
|
||||
uint32_t odr;
|
||||
/** Initial value for CRL register.*/
|
||||
uint32_t crl;
|
||||
/** Initial value for CRH register.*/
|
||||
uint32_t crh;
|
||||
} stm32_gpio_setup_t;
|
||||
|
||||
/**
|
||||
* @brief STM32 GPIO static initializer.
|
||||
* @details An instance of this structure must be passed to @p palInit() at
|
||||
* system startup time in order to initialized the digital I/O
|
||||
* subsystem. This represents only the initial setup, specific pads
|
||||
* or whole ports can be reprogrammed at later time.
|
||||
*/
|
||||
typedef struct {
|
||||
/** @brief Port A setup data.*/
|
||||
stm32_gpio_setup_t PAData;
|
||||
/** @brief Port B setup data.*/
|
||||
stm32_gpio_setup_t PBData;
|
||||
/** @brief Port C setup data.*/
|
||||
stm32_gpio_setup_t PCData;
|
||||
/** @brief Port D setup data.*/
|
||||
stm32_gpio_setup_t PDData;
|
||||
#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
|
||||
/** @brief Port E setup data.*/
|
||||
stm32_gpio_setup_t PEData;
|
||||
#endif
|
||||
#if defined(STM32F10X_HD) || defined(__DOXYGEN__)
|
||||
/** @brief Port F setup data.*/
|
||||
stm32_gpio_setup_t PFData;
|
||||
/** @brief Port G setup data.*/
|
||||
stm32_gpio_setup_t PGData;
|
||||
#endif
|
||||
} STM32GPIOConfig;
|
||||
|
||||
/**
|
||||
* @brief Width, in bits, of an I/O port.
|
||||
*/
|
||||
#define PAL_IOPORTS_WIDTH 16
|
||||
|
||||
/**
|
||||
* @brief Whole port mask.
|
||||
* @brief This macro specifies all the valid bits into a port.
|
||||
*/
|
||||
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
|
||||
|
||||
/**
|
||||
* @brief Digital I/O port sized unsigned type.
|
||||
*/
|
||||
typedef uint32_t ioportmask_t;
|
||||
|
||||
/**
|
||||
* @brief Port Identifier.
|
||||
* @details This type can be a scalar or some kind of pointer, do not make
|
||||
* any assumption about it, use the provided macros when populating
|
||||
* variables of this type.
|
||||
*/
|
||||
typedef GPIO_TypeDef * ioportid_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I/O Ports Identifiers. */
|
||||
/* The low level driver wraps the definitions already present in the STM32 */
|
||||
/* firmware library. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief GPIO port A identifier.
|
||||
*/
|
||||
#define IOPORT_A GPIOA
|
||||
|
||||
/**
|
||||
* @brief GPIO port B identifier.
|
||||
*/
|
||||
#define IOPORT_B GPIOB
|
||||
|
||||
/**
|
||||
* @brief GPIO port C identifier.
|
||||
*/
|
||||
#define IOPORT_C GPIOC
|
||||
|
||||
/**
|
||||
* @brief GPIO port D identifier.
|
||||
*/
|
||||
#define IOPORT_D GPIOD
|
||||
|
||||
/**
|
||||
* @brief GPIO port E identifier.
|
||||
*/
|
||||
#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
|
||||
#define IOPORT_E GPIOE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPIO port F identifier.
|
||||
*/
|
||||
#if defined(STM32F10X_HD) || defined(__DOXYGEN__)
|
||||
#define IOPORT_F GPIOF
|
||||
|
||||
/**
|
||||
* @brief GPIO port G identifier.
|
||||
*/
|
||||
#define IOPORT_G GPIOG
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Implementation, some of the following macros could be implemented as */
|
||||
/* functions, please put them in a file named ioports_lld.c if so. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief GPIO ports subsystem initialization.
|
||||
*/
|
||||
#define pal_lld_init(config) _pal_lld_init(config)
|
||||
|
||||
/**
|
||||
* @brief Reads an I/O port.
|
||||
* @details This function is implemented by reading the GPIO IDR register, the
|
||||
* implementation has no side effects.
|
||||
*
|
||||
* @param[in] port the port identifier
|
||||
* @return the port bits
|
||||
*
|
||||
* @note This function is not meant to be invoked directly by the application
|
||||
* code.
|
||||
*/
|
||||
#define pal_lld_readport(port) ((port)->IDR)
|
||||
|
||||
/**
|
||||
* @brief Reads the output latch.
|
||||
* @details This function is implemented by reading the GPIO ODR register, the
|
||||
* implementation has no side effects.
|
||||
*
|
||||
* @param[in] port the port identifier
|
||||
* @return The latched logical states.
|
||||
*
|
||||
* @note This function is not meant to be invoked directly by the application
|
||||
* code.
|
||||
*/
|
||||
#define pal_lld_readlatch(port) ((port)->ODR)
|
||||
|
||||
/**
|
||||
* @brief Writes on a I/O port.
|
||||
* @details This function is implemented by writing the GPIO ODR register, the
|
||||
* implementation has no side effects.
|
||||
*
|
||||
* @param[in] port the port identifier
|
||||
* @param[in] bits the bits to be written on the specified port
|
||||
*
|
||||
* @note This function is not meant to be invoked directly by the application
|
||||
* code.
|
||||
* @note Writing on pads programmed as pull-up or pull-down has the side
|
||||
* effect to modify the resistor setting because the output latched data
|
||||
* is used for the resistor selection.
|
||||
*/
|
||||
#define pal_lld_writeport(port, bits) ((port)->ODR = (bits))
|
||||
|
||||
/**
|
||||
* @brief Sets a bits mask on a I/O port.
|
||||
* @details This function is implemented by writing the GPIO BSRR register, the
|
||||
* implementation has no side effects.
|
||||
*
|
||||
* @param[in] port the port identifier
|
||||
* @param[in] bits the bits to be ORed on the specified port
|
||||
*
|
||||
* @note This function is not meant to be invoked directly by the application
|
||||
* code.
|
||||
* @note Writing on pads programmed as pull-up or pull-down has the side
|
||||
* effect to modify the resistor setting because the output latched data
|
||||
* is used for the resistor selection.
|
||||
*/
|
||||
#define pal_lld_setport(port, bits) ((port)->BSRR = (bits))
|
||||
|
||||
/**
|
||||
* @brief Clears a bits mask on a I/O port.
|
||||
* @details This function is implemented by writing the GPIO BRR register, the
|
||||
* implementation has no side effects.
|
||||
*
|
||||
* @param[in] port the port identifier
|
||||
* @param[in] bits the bits to be cleared on the specified port
|
||||
*
|
||||
* @note This function is not meant to be invoked directly by the application
|
||||
* code.
|
||||
* @note Writing on pads programmed as pull-up or pull-down has the side
|
||||
* effect to modify the resistor setting because the output latched data
|
||||
* is used for the resistor selection.
|
||||
*/
|
||||
#define pal_lld_clearport(port, bits) ((port)->BRR = (bits))
|
||||
|
||||
/**
|
||||
* @brief Writes a group of bits.
|
||||
* @details This function is implemented by writing the GPIO BSRR register, the
|
||||
* implementation has no side effects.
|
||||
*
|
||||
* @param[in] port the port identifier
|
||||
* @param[in] mask the group mask
|
||||
* @param[in] offset the group bit offset within the port
|
||||
* @param[in] bits the bits to be written. Values exceeding the group width
|
||||
* are masked.
|
||||
*
|
||||
* @note This function is not meant to be invoked directly by the application
|
||||
* code.
|
||||
* @note Writing on pads programmed as pull-up or pull-down has the side
|
||||
* effect to modify the resistor setting because the output latched data
|
||||
* is used for the resistor selection.
|
||||
*/
|
||||
#define pal_lld_writegroup(port, mask, offset, bits) { \
|
||||
(port)->BSRR = ((~(bits) & (mask)) << (16 + (offset))) | \
|
||||
(((bits) & (mask)) << (offset)); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pads group mode setup.
|
||||
* @details This function programs a pads group belonging to the same port
|
||||
* with the specified mode.
|
||||
*
|
||||
* @param[in] port the port identifier
|
||||
* @param[in] mask the group mask
|
||||
* @param[in] mode the mode
|
||||
*
|
||||
* @note This function is not meant to be invoked directly by the application
|
||||
* code.
|
||||
* @note Writing on pads programmed as pull-up or pull-down has the side
|
||||
* effect to modify the resistor setting because the output latched data
|
||||
* is used for the resistor selection.
|
||||
*/
|
||||
#define pal_lld_setgroupmode(port, mask, mode) \
|
||||
_pal_lld_setgroupmode(port, mask, mode)
|
||||
|
||||
/**
|
||||
* @brief Writes a logical state on an output pad.
|
||||
*
|
||||
* @param[in] port the port identifier
|
||||
* @param[in] pad the pad number within the port
|
||||
* @param[out] bit the logical value, the value must be @p 0 or @p 1
|
||||
*
|
||||
* @note This function is not meant to be invoked directly by the application
|
||||
* code.
|
||||
* @note Writing on pads programmed as pull-up or pull-down has the side
|
||||
* effect to modify the resistor setting because the output latched data
|
||||
* is used for the resistor selection.
|
||||
*/
|
||||
#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _pal_lld_init(const STM32GPIOConfig *config);
|
||||
void _pal_lld_setgroupmode(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
uint_fast8_t mode);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F103 STM32F103 Support
|
||||
* @brief STM32F103 specific support.
|
||||
* @details The STM32F103 support includes:
|
||||
* - I/O ports driver.
|
||||
* - Buffered, interrupt driven, serial driver.
|
||||
* - A demo supporting the kernel test suite.
|
||||
* .
|
||||
* @ingroup ARMCM3
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F103_PAL I/O Ports Support
|
||||
* @brief I/O Ports peripherals support.
|
||||
* @details This module supports the STM32F103 GPIO controller. The controller
|
||||
* supports the following features (see @ref PAL):
|
||||
* - 16 bits wide ports.
|
||||
* - Atomic set/reset functions.
|
||||
* - Atomic set+reset function (atomic bus operations).
|
||||
* - Output latched regardless of the pad setting.
|
||||
* - Direct read of input pads regardless of the pad setting.
|
||||
* .
|
||||
* <h2>Supported Setup Modes</h2>
|
||||
* - @p PAL_MODE_RESET.
|
||||
* - @p PAL_MODE_UNCONNECTED.
|
||||
* - @p PAL_MODE_INPUT.
|
||||
* - @p PAL_MODE_INPUT_PULLUP.
|
||||
* - @p PAL_MODE_INPUT_PULLDOWN.
|
||||
* - @p PAL_MODE_OUTPUT_PUSHPULL.
|
||||
* - @p PAL_MODE_OUTPUT_OPENDRAIN.
|
||||
* .
|
||||
* Any attempt to setup an invalid mode is ignored.
|
||||
*
|
||||
* <h2>Suboptimal Behavior</h2>
|
||||
* Some GPIO features are less than optimal:
|
||||
* - Pad/port toggling operations are not atomic.
|
||||
* - Pad/group mode setup is not atomic.
|
||||
* - Writing on pads/groups/ports programmed as input with pull-up/down
|
||||
* resistor can change the resistor setting because the output latch is
|
||||
* used for resistor selection.
|
||||
* .
|
||||
* @ingroup STM32F103
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F103_SERIAL USART Support
|
||||
* @brief USART peripherals support.
|
||||
* @details The serial driver supports the STM32F103 USARTs in asynchronous
|
||||
* mode.
|
||||
*
|
||||
* @ingroup STM32F103
|
||||
*/
|
||||
|
|
@ -0,0 +1,304 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file STM32F103/serial_lld.c
|
||||
* @brief STM32F103 low level serial driver code
|
||||
* @addtogroup STM32F103_SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <ch.h>
|
||||
#include <serial.h>
|
||||
|
||||
#include "nvic.h"
|
||||
#include "board.h"
|
||||
|
||||
#if USE_STM32_USART1 || defined(__DOXYGEN__)
|
||||
/** @brief USART1 serial driver identifier.*/
|
||||
SerialDriver COM1;
|
||||
#endif
|
||||
|
||||
#if USE_STM32_USART2 || defined(__DOXYGEN__)
|
||||
/** @brief USART2 serial driver identifier.*/
|
||||
SerialDriver COM2;
|
||||
#endif
|
||||
|
||||
#if USE_STM32_USART3 || defined(__DOXYGEN__)
|
||||
/** @brief USART3 serial driver identifier.*/
|
||||
SerialDriver COM3;
|
||||
#endif
|
||||
|
||||
/** @brief Driver default configuration.*/
|
||||
static const SerialDriverConfig default_config =
|
||||
{
|
||||
38400,
|
||||
0,
|
||||
USART_CR2_STOP1_BITS | USART_CR2_LINEN,
|
||||
0
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief USART initialization.
|
||||
* @details This function must be invoked with interrupts disabled.
|
||||
*
|
||||
* @param[in] u pointer to an USART I/O block
|
||||
* @param[in] config the architecture-dependent serial driver configuration
|
||||
*/
|
||||
static void usart_init(USART_TypeDef *u, const SerialDriverConfig* config) {
|
||||
|
||||
/*
|
||||
* Baud rate setting.
|
||||
*/
|
||||
if (u == USART1)
|
||||
u->BRR = APB2CLK / config->baud_rate;
|
||||
else
|
||||
u->BRR = APB1CLK / config->baud_rate;
|
||||
|
||||
/*
|
||||
* Note that some bits are enforced.
|
||||
*/
|
||||
u->CR1 = config->cr1 | USART_CR1_UE | USART_CR1_PEIE | USART_CR1_RXNEIE |
|
||||
USART_CR1_TE | USART_CR1_RE;
|
||||
u->CR2 = config->cr2;
|
||||
u->CR3 = config->cr3 | USART_CR3_EIE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART de-initialization.
|
||||
* @details This function must be invoked with interrupts disabled.
|
||||
*
|
||||
* @param[in] u pointer to an USART I/O block
|
||||
*/
|
||||
static void usart_deinit(USART_TypeDef *u) {
|
||||
|
||||
u->CR1 = 0;
|
||||
u->CR2 = 0;
|
||||
u->CR3 = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Error handling routine.
|
||||
* @param[in] sr USART SR register value
|
||||
* @param[in] com communication channel associated to the USART
|
||||
*/
|
||||
static void set_error(uint16_t sr, SerialDriver *sdp) {
|
||||
sdflags_t sts = 0;
|
||||
|
||||
if (sr & USART_SR_ORE)
|
||||
sts |= SD_OVERRUN_ERROR;
|
||||
if (sr & USART_SR_PE)
|
||||
sts |= SD_PARITY_ERROR;
|
||||
if (sr & USART_SR_FE)
|
||||
sts |= SD_FRAMING_ERROR;
|
||||
if (sr & USART_SR_LBD)
|
||||
sts |= SD_BREAK_DETECTED;
|
||||
chSysLockFromIsr();
|
||||
sdAddFlagsI(sdp, sts);
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common IRQ handler.
|
||||
* @param[in] u pointer to an USART I/O block
|
||||
* @param[in] com communication channel associated to the USART
|
||||
*/
|
||||
static void serve_interrupt(USART_TypeDef *u, SerialDriver *sdp) {
|
||||
uint16_t sr = u->SR;
|
||||
|
||||
if (sr & (USART_SR_ORE | USART_SR_FE | USART_SR_PE | USART_SR_LBD))
|
||||
set_error(sr, sdp);
|
||||
if (sr & USART_SR_RXNE) {
|
||||
chSysLockFromIsr();
|
||||
sdIncomingDataI(sdp, u->DR);
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
if (sr & USART_SR_TXE) {
|
||||
chSysLockFromIsr();
|
||||
msg_t b = sdRequestDataI(sdp);
|
||||
chSysUnlockFromIsr();
|
||||
if (b < Q_OK)
|
||||
u->CR1 &= ~USART_CR1_TXEIE;
|
||||
else
|
||||
u->DR = b;
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_STM32_USART1 || defined(__DOXYGEN__)
|
||||
static void notify1(void) {
|
||||
|
||||
USART1->CR1 |= USART_CR1_TXEIE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_STM32_USART2 || defined(__DOXYGEN__)
|
||||
static void notify2(void) {
|
||||
|
||||
USART2->CR1 |= USART_CR1_TXEIE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_STM32_USART3 || defined(__DOXYGEN__)
|
||||
static void notify3(void) {
|
||||
|
||||
USART3->CR1 |= USART_CR1_TXEIE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if USE_STM32_USART1 || defined(__DOXYGEN__)
|
||||
CH_IRQ_HANDLER(VectorD4) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
serve_interrupt(USART1, &COM1);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_STM32_USART2 || defined(__DOXYGEN__)
|
||||
CH_IRQ_HANDLER(VectorD8) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
serve_interrupt(USART2, &COM2);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_STM32_USART3 || defined(__DOXYGEN__)
|
||||
CH_IRQ_HANDLER(VectorDC) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
serve_interrupt(USART3, &COM3);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* Low level serial driver initialization.
|
||||
*/
|
||||
void sd_lld_init(void) {
|
||||
|
||||
#if USE_STM32_USART1
|
||||
sdObjectInit(&COM1, NULL, notify1);
|
||||
GPIOA->CRH = (GPIOA->CRH & 0xFFFFF00F) | 0x000004B0;
|
||||
#endif
|
||||
|
||||
#if USE_STM32_USART2
|
||||
sdObjectInit(&COM2, NULL, notify2);
|
||||
GPIOA->CRL = (GPIOA->CRL & 0xFFFF00FF) | 0x00004B00;
|
||||
#endif
|
||||
|
||||
#if USE_STM32_USART3
|
||||
sdObjectInit(&COM3, NULL, notify3);
|
||||
GPIOB->CRH = (GPIOB->CRH & 0xFFFF00FF) | 0x00004B00;
|
||||
#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.
|
||||
*/
|
||||
void sd_lld_start(SerialDriver *sdp, const SerialDriverConfig *config) {
|
||||
|
||||
if (config == NULL)
|
||||
config = &default_config;
|
||||
|
||||
#if USE_STM32_USART1
|
||||
if (&COM1 == sdp) {
|
||||
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||
usart_init(USART1, config);
|
||||
NVICEnableVector(USART1_IRQn, STM32_USART1_PRIORITY);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if USE_STM32_USART2
|
||||
if (&COM2 == sdp) {
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
|
||||
usart_init(USART2, config);
|
||||
NVICEnableVector(USART2_IRQn, STM32_USART2_PRIORITY);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if USE_STM32_USART3
|
||||
if (&COM3 == sdp) {
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
|
||||
usart_init(USART3, config);
|
||||
NVICEnableVector(USART3_IRQn, STM32_USART3_PRIORITY);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
void sd_lld_stop(SerialDriver *sdp) {
|
||||
|
||||
#if USE_STM32_USART1
|
||||
if (&COM1 == sdp) {
|
||||
usart_deinit(USART1);
|
||||
RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN;
|
||||
NVICDisableVector(USART1_IRQn);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if USE_STM32_USART2
|
||||
if (&COM2 == sdp) {
|
||||
usart_deinit(USART2);
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN;
|
||||
NVICDisableVector(USART2_IRQn);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if USE_STM32_USART3
|
||||
if (&COM3 == sdp) {
|
||||
usart_deinit(USART3);
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN;
|
||||
NVICDisableVector(USART3_IRQn);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file STM32F103/serial_lld.h
|
||||
* @brief STM32F103 low level serial driver header
|
||||
* @addtogroup STM32F103_SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SERIAL_LLD_H_
|
||||
#define _SERIAL_LLD_H_
|
||||
|
||||
/*
|
||||
* Tricks required to make the TRUE/FALSE declaration inside the library
|
||||
* compatible.
|
||||
*/
|
||||
#ifndef __STM32F10x_H
|
||||
#undef FALSE
|
||||
#undef TRUE
|
||||
#include <stm32f10x.h>
|
||||
#define FALSE 0
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Serial buffers size setting.
|
||||
* @details Configuration parameter, you can change the depth of the queue
|
||||
* buffers depending on the requirements of your application.
|
||||
* @note The default is 128 bytes for both the transmission and receive buffers.
|
||||
*/
|
||||
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_BUFFERS_SIZE 128
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief USART1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for USART1 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(USE_STM32_USART1) || defined(__DOXYGEN__)
|
||||
#define USE_STM32_USART1 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief USART2 driver enable switch.
|
||||
* @details If set to @p TRUE the support for USART2 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(USE_STM32_USART2) || defined(__DOXYGEN__)
|
||||
#define USE_STM32_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 FALSE.
|
||||
*/
|
||||
#if !defined(USE_STM32_USART3) || defined(__DOXYGEN__)
|
||||
#define USE_STM32_USART3 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief USART1 interrupt priority level setting.
|
||||
* @note @p BASEPRI_KERNEL >= @p STM32_USART1_PRIORITY > @p PRIORITY_PENDSV.
|
||||
*/
|
||||
#if !defined(STM32_USART1_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_USART1_PRIORITY 0xC0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief USART2 interrupt priority level setting.
|
||||
* @note @p BASEPRI_KERNEL >= @p STM32_USART2_PRIORITY > @p PRIORITY_PENDSV.
|
||||
*/
|
||||
#if !defined(STM32_USART2_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_USART2_PRIORITY 0xC0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief USART3 interrupt priority level setting.
|
||||
* @note @p BASEPRI_KERNEL >= @p STM32_USART3_PRIORITY > @p PRIORITY_PENDSV.
|
||||
*/
|
||||
#if !defined(STM32_USART3_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_USART3_PRIORITY 0xC0
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Extra USARTs definitions here (missing from the ST header file).
|
||||
*/
|
||||
#define USART_CR2_STOP1_BITS (0 << 12) /**< @brief CR2 1 stop bit value.*/
|
||||
#define USART_CR2_STOP0P5_BITS (1 << 12) /**< @brief CR2 0.5 stop bit value.*/
|
||||
#define USART_CR2_STOP2_BITS (2 << 12) /**< @brief CR2 2 stop bit value.*/
|
||||
#define USART_CR2_STOP1P5_BITS (3 << 12) /**< @brief CR2 1.5 stop bit value.*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* Serial Driver condition flags type.
|
||||
*/
|
||||
typedef uint32_t sdflags_t;
|
||||
|
||||
/**
|
||||
* @brief @p SerialDriver specific data.
|
||||
*/
|
||||
struct _serial_driver_data {
|
||||
/**
|
||||
* Input queue, incoming data can be read from this input queue by
|
||||
* using the queues APIs.
|
||||
*/
|
||||
InputQueue iqueue;
|
||||
/**
|
||||
* Output queue, outgoing data can be written to this output queue by
|
||||
* using the queues APIs.
|
||||
*/
|
||||
OutputQueue oqueue;
|
||||
/**
|
||||
* Status Change @p EventSource. This event is generated when one or more
|
||||
* condition flags change.
|
||||
*/
|
||||
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];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generic Serial Driver static initializer.
|
||||
* @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 {
|
||||
|
||||
uint32_t baud_rate;
|
||||
uint16_t cr1;
|
||||
uint16_t cr2;
|
||||
uint16_t cr3;
|
||||
} SerialDriverConfig;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @cond never*/
|
||||
#if USE_STM32_USART1
|
||||
extern SerialDriver COM1;
|
||||
#endif
|
||||
#if USE_STM32_USART2
|
||||
extern SerialDriver COM2;
|
||||
#endif
|
||||
#if USE_STM32_USART3
|
||||
extern SerialDriver COM3;
|
||||
#endif
|
||||
/** @endcond*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void sd_lld_init(void);
|
||||
void sd_lld_start(SerialDriver *sdp, const SerialDriverConfig *config);
|
||||
void sd_lld_stop(SerialDriver *sdp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SERIAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file STM32F103/stm32_can.c
|
||||
* @brief STM32 CAN driver code
|
||||
* @addtogroup STM32F103_CAN
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file STM32F103/stm32_can.h
|
||||
* @brief STM32 CAN driver header file
|
||||
* @addtogroup STM32F103_CAN
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _STM32_CAN_H_
|
||||
#define _STM32_CAN_H_
|
||||
|
||||
typedef struct {
|
||||
} CANConfig;
|
||||
|
||||
typedef struct {
|
||||
} CANMessage;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void canInit(CANConfig *config);
|
||||
bool_t canReceive(CANMessage *canmsg);
|
||||
bool_t canTransmit(CANMessage *canmsg);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _STM32_CAN_H_ */
|
||||
|
||||
/** @} */
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue