From dbd493cff1bb0c9b0bdd3eeb081a56dbaa0235a8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 17 Aug 2013 15:32:41 +0000 Subject: [PATCH] I2C ported but needs to be reviewed to not use virtual timers directly. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6170 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM4-STM32F303-DISCOVERY/halconf.h | 2 +- demos/ARMCM4-STM32F303-DISCOVERY/mcuconf.h | 6 +- os/hal/hal.mk | 1 + os/hal/include/hal.h | 2 +- os/hal/include/i2c.h | 144 ++++++++++ os/hal/platforms/STM32/I2Cv2/i2c_lld.c | 120 ++++----- os/hal/platforms/STM32/I2Cv2/i2c_lld.h | 58 ++-- os/hal/platforms/STM32/SPIv2/spi_lld.h | 79 ++---- os/hal/platforms/STM32/USARTv2/uart_lld.h | 77 ++---- os/hal/platforms/STM32F30x/stm32_registry.h | 250 ++++++++--------- os/hal/src/i2c.c | 283 ++++++++++++++++++++ 11 files changed, 686 insertions(+), 336 deletions(-) create mode 100644 os/hal/include/i2c.h create mode 100644 os/hal/src/i2c.c diff --git a/demos/ARMCM4-STM32F303-DISCOVERY/halconf.h b/demos/ARMCM4-STM32F303-DISCOVERY/halconf.h index 21836f994..8a42407e6 100644 --- a/demos/ARMCM4-STM32F303-DISCOVERY/halconf.h +++ b/demos/ARMCM4-STM32F303-DISCOVERY/halconf.h @@ -69,7 +69,7 @@ * @brief Enables the I2C subsystem. */ #if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) -#define HAL_USE_I2C FALSE +#define HAL_USE_I2C TRUE #endif /** diff --git a/demos/ARMCM4-STM32F303-DISCOVERY/mcuconf.h b/demos/ARMCM4-STM32F303-DISCOVERY/mcuconf.h index 76eea5142..71055d9fa 100644 --- a/demos/ARMCM4-STM32F303-DISCOVERY/mcuconf.h +++ b/demos/ARMCM4-STM32F303-DISCOVERY/mcuconf.h @@ -124,13 +124,13 @@ /* * I2C driver system settings. */ -#define STM32_I2C_USE_I2C1 FALSE -#define STM32_I2C_USE_I2C2 FALSE +#define STM32_I2C_USE_I2C1 TRUE +#define STM32_I2C_USE_I2C2 TRUE #define STM32_I2C_I2C1_IRQ_PRIORITY 10 #define STM32_I2C_I2C2_IRQ_PRIORITY 10 #define STM32_I2C_I2C1_DMA_PRIORITY 1 #define STM32_I2C_I2C2_DMA_PRIORITY 1 -#define STM32_I2C_DMA_ERROR_HOOK(i2cp) chSysHalt() +#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") /* * ICU driver system settings. diff --git a/os/hal/hal.mk b/os/hal/hal.mk index 2323b9dcb..2f024119a 100644 --- a/os/hal/hal.mk +++ b/os/hal/hal.mk @@ -7,6 +7,7 @@ HALSRC = ${CHIBIOS}/os/hal/src/hal.c \ ${CHIBIOS}/os/hal/src/can.c \ ${CHIBIOS}/os/hal/src/ext.c \ ${CHIBIOS}/os/hal/src/gpt.c \ + ${CHIBIOS}/os/hal/src/i2c.c \ ${CHIBIOS}/os/hal/src/icu.c \ ${CHIBIOS}/os/hal/src/mmc_spi.c \ ${CHIBIOS}/os/hal/src/pal.c \ diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h index 453addd1a..dc4816947 100644 --- a/os/hal/include/hal.h +++ b/os/hal/include/hal.h @@ -50,7 +50,7 @@ #include "can.h" #include "ext.h" #include "gpt.h" -//#include "i2c.h" +#include "i2c.h" #include "icu.h" //#include "mac.h" #include "pwm.h" diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h new file mode 100644 index 000000000..b70767609 --- /dev/null +++ b/os/hal/include/i2c.h @@ -0,0 +1,144 @@ +/* + 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 . +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file i2c.h + * @brief I2C Driver macros and structures. + * + * @addtogroup I2C + * @{ + */ + +#ifndef _I2C_H_ +#define _I2C_H_ + +#if HAL_USE_I2C || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/* TODO: To be reviewed, too STM32-centric.*/ +/** + * @name I2C bus error conditions + * @{ + */ +#define I2C_NO_ERROR 0x00 /**< @brief No error. */ +#define I2C_BUS_ERROR 0x01 /**< @brief Bus Error. */ +#define I2C_ARBITRATION_LOST 0x02 /**< @brief Arbitration Lost. */ +#define I2C_ACK_FAILURE 0x04 /**< @brief Acknowledge Failure. */ +#define I2C_OVERRUN 0x08 /**< @brief Overrun/Underrun. */ +#define I2C_PEC_ERROR 0x10 /**< @brief PEC Error in + reception. */ +#define I2C_TIMEOUT 0x20 /**< @brief Hardware timeout. */ +#define I2C_SMB_ALERT 0x40 /**< @brief SMBus Alert. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define I2C_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Driver state machine possible states. + */ +typedef enum { + I2C_UNINIT = 0, /**< Not initialized. */ + I2C_STOP = 1, /**< Stopped. */ + I2C_READY = 2, /**< Ready. */ + I2C_ACTIVE_TX = 3, /**< Transmitting. */ + I2C_ACTIVE_RX = 4, /**< Receiving. */ + I2C_LOCKED = 5 /**> Bus or driver locked. */ +} i2cstate_t; + +#include "i2c_lld.h" + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Wrap i2cMasterTransmitTimeout function with TIME_INFINITE timeout. + * @api + */ +#define i2cMasterTransmit(i2cp, addr, txbuf, txbytes, rxbuf, rxbytes) \ + (i2cMasterTransmitTimeout(i2cp, addr, txbuf, txbytes, rxbuf, rxbytes, \ + TIME_INFINITE)) + +/** + * @brief Wrap i2cMasterReceiveTimeout function with TIME_INFINITE timeout. + * @api + */ +#define i2cMasterReceive(i2cp, addr, rxbuf, rxbytes) \ + (i2cMasterReceiveTimeout(i2cp, addr, rxbuf, rxbytes, TIME_INFINITE)) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void i2cInit(void); + void i2cObjectInit(I2CDriver *i2cp); + void i2cStart(I2CDriver *i2cp, const I2CConfig *config); + void i2cStop(I2CDriver *i2cp); + i2cflags_t i2cGetErrors(I2CDriver *i2cp); + msg_t i2cMasterTransmitTimeout(I2CDriver *i2cp, + i2caddr_t addr, + const uint8_t *txbuf, size_t txbytes, + uint8_t *rxbuf, size_t rxbytes, + systime_t timeout); + msg_t i2cMasterReceiveTimeout(I2CDriver *i2cp, + i2caddr_t addr, + uint8_t *rxbuf, size_t rxbytes, + systime_t timeout); +#if I2C_USE_MUTUAL_EXCLUSION + void i2cAcquireBus(I2CDriver *i2cp); + void i2cReleaseBus(I2CDriver *i2cp); +#endif /* I2C_USE_MUTUAL_EXCLUSION */ + +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_I2C */ + +#endif /* _I2C_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32/I2Cv2/i2c_lld.c b/os/hal/platforms/STM32/I2Cv2/i2c_lld.c index 1050dc08f..5cdebd052 100644 --- a/os/hal/platforms/STM32/I2Cv2/i2c_lld.c +++ b/os/hal/platforms/STM32/I2Cv2/i2c_lld.c @@ -26,7 +26,6 @@ * @{ */ -#include "ch.h" #include "hal.h" #if HAL_USE_I2C || defined(__DOXYGEN__) @@ -102,14 +101,14 @@ I2CDriver I2CD2; * @notapi */ #define wakeup_isr(i2cp, msg) { \ - chSysLockFromIsr(); \ + osalSysLockFromISR(); \ if ((i2cp)->thread != NULL) { \ - Thread *tp = (i2cp)->thread; \ + thread_t *tp = (i2cp)->thread; \ (i2cp)->thread = NULL; \ tp->p_u.rdymsg = (msg); \ chSchReadyI(tp); \ } \ - chSysUnlockFromIsr(); \ + osalSysUnlockFromISR(); \ } /** @@ -145,15 +144,15 @@ static void i2c_lld_abort_operation(I2CDriver *i2cp) { static void i2c_lld_safety_timeout(void *p) { I2CDriver *i2cp = (I2CDriver *)p; - chSysLockFromIsr(); + osalSysLockFromISR(); if (i2cp->thread) { - Thread *tp = i2cp->thread; + thread_t *tp = i2cp->thread; i2c_lld_abort_operation(i2cp); i2cp->thread = NULL; - tp->p_u.rdymsg = RDY_TIMEOUT; + tp->p_u.rdymsg = MSG_TIMEOUT; chSchReadyI(tp); } - chSysUnlockFromIsr(); + osalSysUnlockFromISR(); } /** @@ -196,7 +195,7 @@ static void i2c_lld_serve_interrupt(I2CDriver *i2cp, uint32_t isr) { /* Starts a STOP sequence immediately on error.*/ dp->CR2 |= I2C_CR2_STOP; - i2cp->errors |= I2CD_ACK_FAILURE; + i2cp->errors |= I2C_ACK_FAILURE; } if (isr & I2C_ISR_STOPF) { /* Stops the associated DMA streams.*/ @@ -204,10 +203,10 @@ static void i2c_lld_serve_interrupt(I2CDriver *i2cp, uint32_t isr) { dmaStreamDisable(i2cp->dmarx); if (i2cp->errors) { - wakeup_isr(i2cp, RDY_RESET); + wakeup_isr(i2cp, MSG_RESET); } else { - wakeup_isr(i2cp, RDY_OK); + wakeup_isr(i2cp, MSG_OK); } } } @@ -234,7 +233,7 @@ static void i2c_lld_serve_rx_end_irq(I2CDriver *i2cp, uint32_t flags) { dmaStreamDisable(i2cp->dmarx); dp->CR2 |= I2C_CR2_STOP; - wakeup_isr(i2cp, RDY_OK); + wakeup_isr(i2cp, MSG_OK); } /** @@ -273,20 +272,20 @@ static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint32_t isr) { dmaStreamDisable(i2cp->dmarx); if (isr & I2C_ISR_BERR) - i2cp->errors |= I2CD_BUS_ERROR; + i2cp->errors |= I2C_BUS_ERROR; if (isr & I2C_ISR_ARLO) - i2cp->errors |= I2CD_ARBITRATION_LOST; + i2cp->errors |= I2C_ARBITRATION_LOST; if (isr & I2C_ISR_OVR) - i2cp->errors |= I2CD_OVERRUN; + i2cp->errors |= I2C_OVERRUN; if (isr & I2C_ISR_TIMEOUT) - i2cp->errors |= I2CD_TIMEOUT; + i2cp->errors |= I2C_TIMEOUT; /* If some error has been identified then sends wakes the waiting thread.*/ - if (i2cp->errors != I2CD_NO_ERROR) - wakeup_isr(i2cp, RDY_RESET); + if (i2cp->errors != I2C_NO_ERROR) + wakeup_isr(i2cp, MSG_RESET); } /*===========================================================================*/ @@ -452,29 +451,27 @@ void i2c_lld_start(I2CDriver *i2cp) { #if STM32_I2C_USE_I2C1 if (&I2CD1 == i2cp) { - bool_t b; + bool b; rccResetI2C1(); b = dmaStreamAllocate(i2cp->dmarx, STM32_I2C_I2C1_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, (void *)i2cp); - chDbgAssert(!b, "i2c_lld_start(), #1", "stream already allocated"); + osalDbgAssert(!b, "stream already allocated"); b = dmaStreamAllocate(i2cp->dmatx, STM32_I2C_I2C1_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, (void *)i2cp); - chDbgAssert(!b, "i2c_lld_start(), #2", "stream already allocated"); + osalDbgAssert(!b, "stream already allocated"); rccEnableI2C1(FALSE); #if defined(STM32_I2C1_GLOBAL_NUMBER) || defined(__DOXYGEN__) nvicEnableVector(STM32_I2C1_GLOBAL_NUMBER, CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); #elif defined(STM32_I2C1_EVENT_NUMBER) && defined(STM32_I2C1_ERROR_NUMBER) - nvicEnableVector(STM32_I2C1_EVENT_NUMBER, - CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); - nvicEnableVector(STM32_I2C1_ERROR_NUMBER, - CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); + nvicEnableVector(STM32_I2C1_EVENT_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY); + nvicEnableVector(STM32_I2C1_ERROR_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY); #else #error "I2C1 interrupt numbers not defined" #endif @@ -488,29 +485,27 @@ void i2c_lld_start(I2CDriver *i2cp) { #if STM32_I2C_USE_I2C2 if (&I2CD2 == i2cp) { - bool_t b; + bool b; rccResetI2C2(); b = dmaStreamAllocate(i2cp->dmarx, STM32_I2C_I2C2_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, (void *)i2cp); - chDbgAssert(!b, "i2c_lld_start(), #3", "stream already allocated"); + osalDbgAssert(!b, "stream already allocated"); b = dmaStreamAllocate(i2cp->dmatx, STM32_I2C_I2C2_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, (void *)i2cp); - chDbgAssert(!b, "i2c_lld_start(), #4", "stream already allocated"); + osalDbgAssert(!b, "stream already allocated"); rccEnableI2C2(FALSE); #if defined(STM32_I2C2_GLOBAL_NUMBER) || defined(__DOXYGEN__) nvicEnableVector(STM32_I2C2_GLOBAL_NUMBER, CORTEX_PRIORITY_MASK(STM32_I2C_I2C2_IRQ_PRIORITY)); #elif defined(STM32_I2C2_EVENT_NUMBER) && defined(STM32_I2C2_ERROR_NUMBER) - nvicEnableVector(STM32_I2C2_EVENT_NUMBER, - CORTEX_PRIORITY_MASK(STM32_I2C_I2C2_IRQ_PRIORITY)); - nvicEnableVector(STM32_I2C2_ERROR_NUMBER, - CORTEX_PRIORITY_MASK(STM32_I2C_I2C2_IRQ_PRIORITY)); + nvicEnableVector(STM32_I2C2_EVENT_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY); + nvicEnableVector(STM32_I2C2_ERROR_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY); #else #error "I2C2 interrupt numbers not defined" #endif @@ -604,10 +599,10 @@ void i2c_lld_stop(I2CDriver *i2cp) { * - @a TIME_INFINITE no timeout. * . * @return The operation status. - * @retval RDY_OK if the function succeeded. - * @retval RDY_RESET if one or more I2C errors occurred, the errors can + * @retval MSG_OK if the function succeeded. + * @retval MSG_RESET if one or more I2C errors occurred, the errors can * be retrieved using @p i2cGetErrors(). - * @retval RDY_TIMEOUT if a timeout occurred before operation end. After a + * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a * timeout the driver must be stopped and restarted * because the bus is in an uncertain state. * @@ -617,32 +612,32 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr, uint8_t *rxbuf, size_t rxbytes, systime_t timeout) { I2C_TypeDef *dp = i2cp->i2c; - VirtualTimer vt; + virtual_timer_t vt; uint32_t addr_cr2 = addr & I2C_CR2_SADD; - chDbgCheck((rxbytes > 0), "i2c_lld_master_receive_timeout"); + osalDbgCheck((rxbytes > 0)); /* Resetting error flags for this transfer.*/ - i2cp->errors = I2CD_NO_ERROR; + i2cp->errors = I2C_NO_ERROR; /* Global timeout for the whole operation.*/ if (timeout != TIME_INFINITE) chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp); /* Releases the lock from high level driver.*/ - chSysUnlock(); + osalSysUnlock(); /* Waits until BUSY flag is reset and the STOP from the previous operation is completed, alternatively for a timeout condition.*/ while (dp->ISR & I2C_ISR_BUSY) { - chSysLock(); + osalSysLock(); if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt)) - return RDY_TIMEOUT; - chSysUnlock(); + return MSG_TIMEOUT; + osalSysUnlock(); } /* This lock will be released in high level driver.*/ - chSysLock(); + osalSysLock(); /* Adjust slave address (master mode) for 7-bit address mode */ if ((i2cp->config->cr2 & I2C_CR2_ADD10) == 0) @@ -666,19 +661,19 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr, /* Atomic check on the timer in order to make sure that a timeout didn't happen outside the critical zone.*/ if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt)) - return RDY_TIMEOUT; + return MSG_TIMEOUT; /* Starts the operation.*/ dp->CR2 |= I2C_CR2_RD_WRN; dp->CR2 |= I2C_CR2_START; /* Waits for the operation completion or a timeout.*/ - i2cp->thread = chThdSelf(); - chSchGoSleepS(THD_STATE_SUSPENDED); + i2cp->thread = chThdGetSelfX(); + chSchGoSleepS(CH_STATE_SUSPENDED); if ((timeout != TIME_INFINITE) && chVTIsArmedI(&vt)) chVTResetI(&vt); - return chThdSelf()->p_u.rdymsg; + return chThdGetSelfX()->p_u.rdymsg; } /** @@ -697,10 +692,10 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr, * - @a TIME_INFINITE no timeout. * . * @return The operation status. - * @retval RDY_OK if the function succeeded. - * @retval RDY_RESET if one or more I2C errors occurred, the errors can + * @retval MSG_OK if the function succeeded. + * @retval MSG_RESET if one or more I2C errors occurred, the errors can * be retrieved using @p i2cGetErrors(). - * @retval RDY_TIMEOUT if a timeout occurred before operation end. After a + * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a * timeout the driver must be stopped and restarted * because the bus is in an uncertain state. * @@ -711,33 +706,32 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr, uint8_t *rxbuf, size_t rxbytes, systime_t timeout) { I2C_TypeDef *dp = i2cp->i2c; - VirtualTimer vt; + virtual_timer_t vt; uint32_t addr_cr2 = addr & I2C_CR2_SADD; - chDbgCheck(((rxbytes == 0) || ((rxbytes > 0) && (rxbuf != NULL))), - "i2c_lld_master_transmit_timeout"); + osalDbgCheck(((rxbytes == 0) || ((rxbytes > 0) && (rxbuf != NULL)))); /* Resetting error flags for this transfer.*/ - i2cp->errors = I2CD_NO_ERROR; + i2cp->errors = I2C_NO_ERROR; /* Global timeout for the whole operation.*/ if (timeout != TIME_INFINITE) chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp); /* Releases the lock from high level driver.*/ - chSysUnlock(); + osalSysUnlock(); /* Waits until BUSY flag is reset and the STOP from the previous operation is completed, alternatively for a timeout condition.*/ while (dp->ISR & I2C_ISR_BUSY) { - chSysLock(); + osalSysLock(); if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt)) - return RDY_TIMEOUT; - chSysUnlock(); + return MSG_TIMEOUT; + osalSysUnlock(); } /* This lock will be released in high level driver.*/ - chSysLock(); + osalSysLock(); /* Adjust slave address (master mode) for 7-bit address mode */ if ((i2cp->config->cr2 & I2C_CR2_ADD10) == 0) @@ -766,7 +760,7 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr, /* Atomic check on the timer in order to make sure that a timeout didn't happen outside the critical zone.*/ if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt)) - return RDY_TIMEOUT; + return MSG_TIMEOUT; /* Transmission complete interrupt enabled.*/ dp->CR1 |= I2C_CR1_TCIE; @@ -776,12 +770,12 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr, dp->CR2 |= I2C_CR2_START; /* Waits for the operation completion or a timeout.*/ - i2cp->thread = chThdSelf(); - chSchGoSleepS(THD_STATE_SUSPENDED); + i2cp->thread = chThdGetSelfX(); + chSchGoSleepS(CH_STATE_SUSPENDED); if ((timeout != TIME_INFINITE) && chVTIsArmedI(&vt)) chVTResetI(&vt); - return chThdSelf()->p_u.rdymsg; + return chThdGetSelfX()->p_u.rdymsg; } #endif /* HAL_USE_I2C */ diff --git a/os/hal/platforms/STM32/I2Cv2/i2c_lld.h b/os/hal/platforms/STM32/I2Cv2/i2c_lld.h index 810c7be84..7bde99a6f 100644 --- a/os/hal/platforms/STM32/I2Cv2/i2c_lld.h +++ b/os/hal/platforms/STM32/I2Cv2/i2c_lld.h @@ -117,7 +117,7 @@ * error can only happen because programming errors. */ #if !defined(STM32_I2C_DMA_ERROR_HOOK) || defined(__DOXYGEN__) -#define STM32_I2C_DMA_ERROR_HOOK(i2cp) chSysHalt() +#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") #endif /** @} */ @@ -125,21 +125,20 @@ /* Derived constants and error checks. */ /*===========================================================================*/ -/* Streams for the DMA peripheral.*/ +/* TODO: Move the following DMA settings in the STM32F0XX registry.*/ #if defined(STM32F0XX) #define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) #define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) #define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#endif -#elif defined(STM32F30X) || defined(STM32F37X) +/* TODO: Move the following DMA settings in the STM32F37X registry.*/ +#if defined(STM32F37X) #define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) #define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) #define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) #define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) - -#else -#error "device unsupported by I2Cv2 driver" #endif /** @brief error checks */ @@ -155,6 +154,41 @@ #error "I2C driver activated but no I2C peripheral assigned" #endif +#if STM32_I2C_USE_I2C1 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_I2C_I2C1_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to I2C1" +#endif + +#if STM32_I2C_USE_I2C2 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_I2C_I2C2_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to I2C2" +#endif + +#if STM32_I2C_USE_I2C1 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C1_DMA_PRIORITY) +#error "Invalid DMA priority assigned to I2C1" +#endif + +#if STM32_I2C_USE_I2C2 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C2_DMA_PRIORITY) +#error "Invalid DMA priority assigned to I2C2" +#endif + +/* The following checks are only required when there is a DMA able to + reassign streams to different channels.*/ +#if STM32_ADVANCED_DMA +/* Check on the presence of the DMA streams settings in mcuconf.h.*/ +#if STM32_I2C_USE_I2C1 && (!defined(STM32_I2C_I2C1_RX_DMA_STREAM) || \ + !defined(STM32_I2C_I2C1_TX_DMA_STREAM)) +#error "I2C1 DMA streams not defined" +#endif + +#if STM32_I2C_USE_I2C2 && (!defined(STM32_I2C_I2C2_RX_DMA_STREAM) || \ + !defined(STM32_I2C_I2C2_TX_DMA_STREAM)) +#error "I2C2 DMA streams not defined" +#endif + +/* Check on the validity of the assigned DMA channels.*/ #if STM32_I2C_USE_I2C1 && \ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_RX_DMA_STREAM, \ STM32_I2C1_RX_DMA_MSK) @@ -178,6 +212,7 @@ STM32_I2C2_TX_DMA_MSK) #error "invalid DMA stream associated to I2C2 TX" #endif +#endif /* STM32_ADVANCED_DMA */ #if !defined(STM32_DMA_REQUIRED) #define STM32_DMA_REQUIRED @@ -243,14 +278,7 @@ struct I2CDriver{ */ i2cflags_t errors; #if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) -#if CH_USE_MUTEXES || defined(__DOXYGEN__) - /** - * @brief Mutex protecting the bus. - */ - Mutex mutex; -#elif CH_USE_SEMAPHORES - Semaphore semaphore; -#endif + mutex_t mutex; #endif /* I2C_USE_MUTUAL_EXCLUSION */ #if defined(I2C_DRIVER_EXT_FIELDS) I2C_DRIVER_EXT_FIELDS @@ -259,7 +287,7 @@ struct I2CDriver{ /** * @brief Thread waiting for I/O completion. */ - Thread *thread; + thread_t *thread; /** * @brief Current slave address without R/W bit. */ diff --git a/os/hal/platforms/STM32/SPIv2/spi_lld.h b/os/hal/platforms/STM32/SPIv2/spi_lld.h index 9f06fa5e5..ceac42b2c 100644 --- a/os/hal/platforms/STM32/SPIv2/spi_lld.h +++ b/os/hal/platforms/STM32/SPIv2/spi_lld.h @@ -124,58 +124,7 @@ #define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") #endif -#if STM32_ADVANCED_DMA || defined(__DOXYGEN__) - -/** - * @brief DMA stream used for SPI1 RX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_SPI_SPI1_RX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) -#endif - -/** - * @brief DMA stream used for SPI1 TX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_SPI_SPI1_TX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) -#endif - -/** - * @brief DMA stream used for SPI2 RX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_SPI_SPI2_RX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) -#endif - -/** - * @brief DMA stream used for SPI2 TX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_SPI_SPI2_TX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) -#endif - -/** - * @brief DMA stream used for SPI3 RX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_SPI_SPI3_RX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) -#endif - -/** - * @brief DMA stream used for SPI3 TX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_SPI_SPI3_TX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) -#endif - -#else /* !STM32_ADVANCED_DMA */ - +/* TODO: Move the following DMA settings in the STM32F0XX registry.*/ #if defined(STM32F0XX) /* Fixed values for STM32F0xx devices.*/ #define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) @@ -184,7 +133,8 @@ #define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) #endif /* defined(STM32F0XX) */ -#if defined(STM32F30X) || defined(STM32F37X) +/* TODO: Move the following DMA settings in the STM32F37X registry.*/ +#if defined(STM32F37X) /* Fixed values for STM32F3xx devices.*/ #define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) @@ -193,8 +143,6 @@ #define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) #define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) #endif /* defined(STM32F30X) */ - -#endif /* !STM32_ADVANCED_DMA*/ /** @} */ /*===========================================================================*/ @@ -247,6 +195,26 @@ #error "Invalid DMA priority assigned to SPI3" #endif +/* The following checks are only required when there is a DMA able to + reassign streams to different channels.*/ +#if STM32_ADVANCED_DMA +/* Check on the presence of the DMA streams settings in mcuconf.h.*/ +#if STM32_SPI_USE_SPI1 && (!defined(STM32_SPI_SPI1_RX_DMA_STREAM) || \ + !defined(STM32_SPI_SPI1_TX_DMA_STREAM)) +#error "SPI1 DMA streams not defined" +#endif + +#if STM32_SPI_USE_SPI2 && (!defined(STM32_SPI_SPI2_RX_DMA_STREAM) || \ + !defined(STM32_SPI_SPI2_TX_DMA_STREAM)) +#error "SPI2 DMA streams not defined" +#endif + +#if STM32_SPI_USE_SPI3 && (!defined(STM32_SPI_SPI3_RX_DMA_STREAM) || \ + !defined(STM32_SPI_SPI3_TX_DMA_STREAM)) +#error "SPI3 DMA streams not defined" +#endif + +/* Check on the validity of the assigned DMA channels.*/ #if STM32_SPI_USE_SPI1 && \ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK) #error "invalid DMA stream associated to SPI1 RX" @@ -276,6 +244,7 @@ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK) #error "invalid DMA stream associated to SPI3 TX" #endif +#endif /* STM32_ADVANCED_DMA */ #if !defined(STM32_DMA_REQUIRED) #define STM32_DMA_REQUIRED diff --git a/os/hal/platforms/STM32/USARTv2/uart_lld.h b/os/hal/platforms/STM32/USARTv2/uart_lld.h index c34123aca..6b4393e96 100644 --- a/os/hal/platforms/STM32/USARTv2/uart_lld.h +++ b/os/hal/platforms/STM32/USARTv2/uart_lld.h @@ -126,58 +126,6 @@ #define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") #endif -#if STM32_ADVANCED_DMA || defined(__DOXYGEN__) - -/** - * @brief DMA stream used for USART1 RX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_UART_USART1_RX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) -#endif - -/** - * @brief DMA stream used for USART1 TX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_UART_USART1_TX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) -#endif - -/** - * @brief DMA stream used for USART2 RX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_UART_USART2_RX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) -#endif - -/** - * @brief DMA stream used for USART2 TX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_UART_USART2_TX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) -#endif - -/** - * @brief DMA stream used for USART3 RX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_UART_USART3_RX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) -#endif - -/** - * @brief DMA stream used for USART3 TX operations. - * @note This option is only available on platforms with enhanced DMA. - */ -#if !defined(STM32_UART_USART3_TX_DMA_STREAM) || defined(__DOXYGEN__) -#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) -#endif - -#else /* !STM32_ADVANCED_DMA*/ - #if defined(STM32F0XX) /* Fixed values for STM32F0xx devices.*/ #define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) @@ -186,7 +134,7 @@ #define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) #endif /* defined(STM32F0XX) */ -#if defined(STM32F30X)|| defined(STM32F37X) +#if defined(STM32F37X) /* Fixed values for STM32F3xx devices.*/ #define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) #define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) @@ -195,8 +143,6 @@ #define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) #define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) #endif /* defined(STM32F30X) */ - -#endif /* !STM32_ADVANCED_DMA*/ /** @} */ /*===========================================================================*/ @@ -250,6 +196,26 @@ #error "Invalid DMA priority assigned to USART3" #endif +/* The following checks are only required when there is a DMA able to + reassign streams to different channels.*/ +#if STM32_ADVANCED_DMA +/* Check on the presence of the DMA streams settings in mcuconf.h.*/ +#if STM32_UART_USE_USART1 && (!defined(STM32_UART_USART1_RX_DMA_STREAM) || \ + !defined(STM32_UART_USART1_TX_DMA_STREAM)) +#error "USART1 DMA streams not defined" +#endif + +#if STM32_UART_USE_USART2 && (!defined(STM32_UART_USART2_RX_DMA_STREAM) || \ + !defined(STM32_UART_USART2_TX_DMA_STREAM)) +#error "USART2 DMA streams not defined" +#endif + +#if STM32_UART_USE_USART3 && (!defined(STM32_UART_USART3_RX_DMA_STREAM) || \ + !defined(STM32_UART_USART3_TX_DMA_STREAM)) +#error "USART3 DMA streams not defined" +#endif + +/* Check on the validity of the assigned DMA channels.*/ #if STM32_UART_USE_USART1 && \ !STM32_DMA_IS_VALID_ID(STM32_UART_USART1_RX_DMA_STREAM, \ STM32_USART1_RX_DMA_MSK) @@ -285,6 +251,7 @@ STM32_USART3_TX_DMA_MSK) #error "invalid DMA stream associated to USART3 TX" #endif +#endif /* STM32_ADVANCED_DMA */ #if !defined(STM32_DMA_REQUIRED) #define STM32_DMA_REQUIRED diff --git a/os/hal/platforms/STM32F30x/stm32_registry.h b/os/hal/platforms/STM32F30x/stm32_registry.h index 20d3dc62b..b2deec625 100644 --- a/os/hal/platforms/STM32F30x/stm32_registry.h +++ b/os/hal/platforms/STM32F30x/stm32_registry.h @@ -34,199 +34,163 @@ * @{ */ /* ADC attributes.*/ -#define STM32_HAS_ADC1 TRUE -#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1)) -#define STM32_ADC1_DMA_CHN 0x00000000 +#define STM32_HAS_ADC1 TRUE -#define STM32_HAS_ADC2 TRUE -#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) | \ - STM32_DMA_STREAM_ID_MSK(2, 3)) -#define STM32_ADC2_DMA_CHN 0x00000000 +#define STM32_HAS_ADC2 TRUE -#define STM32_HAS_ADC3 TRUE -#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_ADC3_DMA_CHN 0x00000000 +#define STM32_HAS_ADC3 TRUE -#define STM32_HAS_ADC4 TRUE -#define STM32_ADC4_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) | \ - STM32_DMA_STREAM_ID_MSK(2, 4)) -#define STM32_ADC4_DMA_CHN 0x00000000 +#define STM32_HAS_ADC4 TRUE -#define STM32_HAS_SDADC1 FALSE -#define STM32_HAS_SDADC2 FALSE -#define STM32_HAS_SDADC3 FALSE +#define STM32_HAS_SDADC1 FALSE +#define STM32_HAS_SDADC2 FALSE +#define STM32_HAS_SDADC3 FALSE /* CAN attributes.*/ -#define STM32_HAS_CAN1 TRUE -#define STM32_HAS_CAN2 FALSE -#define STM32_CAN_MAX_FILTERS 14 +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 FALSE +#define STM32_CAN_MAX_FILTERS 14 /* DAC attributes.*/ -#define STM32_HAS_DAC1 TRUE -#define STM32_HAS_DAC2 TRUE +#define STM32_HAS_DAC1 TRUE +#define STM32_HAS_DAC2 TRUE /* DMA attributes.*/ -#define STM32_ADVANCED_DMA FALSE -#define STM32_HAS_DMA1 TRUE -#define STM32_HAS_DMA2 TRUE +#define STM32_ADVANCED_DMA FALSE +#define STM32_HAS_DMA1 TRUE +#define STM32_HAS_DMA2 TRUE /* ETH attributes.*/ -#define STM32_HAS_ETH FALSE +#define STM32_HAS_ETH FALSE /* EXTI attributes.*/ -#define STM32_EXTI_NUM_CHANNELS 34 +#define STM32_EXTI_NUM_CHANNELS 34 /* GPIO attributes.*/ -#define STM32_HAS_GPIOA TRUE -#define STM32_HAS_GPIOB TRUE -#define STM32_HAS_GPIOC TRUE -#define STM32_HAS_GPIOD TRUE -#define STM32_HAS_GPIOE TRUE -#define STM32_HAS_GPIOF TRUE -#define STM32_HAS_GPIOG FALSE -#define STM32_HAS_GPIOH FALSE -#define STM32_HAS_GPIOI FALSE +#define STM32_HAS_GPIOA TRUE +#define STM32_HAS_GPIOB TRUE +#define STM32_HAS_GPIOC TRUE +#define STM32_HAS_GPIOD TRUE +#define STM32_HAS_GPIOE TRUE +#define STM32_HAS_GPIOF TRUE +#define STM32_HAS_GPIOG FALSE +#define STM32_HAS_GPIOH FALSE +#define STM32_HAS_GPIOI FALSE /* I2C attributes.*/ -#define STM32_HAS_I2C1 TRUE -#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) -#define STM32_I2C1_RX_DMA_CHN 0x00000000 -#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_I2C1_TX_DMA_CHN 0x00000000 +#define STM32_HAS_I2C1 TRUE +#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) -#define STM32_HAS_I2C2 TRUE -#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_I2C2_RX_DMA_CHN 0x00000000 -#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) -#define STM32_I2C2_TX_DMA_CHN 0x00000000 +#define STM32_HAS_I2C2 TRUE +#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) -#define STM32_HAS_I2C3 FALSE -#define STM32_I2C3_RX_DMA_MSK 0 -#define STM32_I2C3_RX_DMA_CHN 0x00000000 -#define STM32_I2C3_TX_DMA_MSK 0 -#define STM32_I2C3_TX_DMA_CHN 0x00000000 +#define STM32_HAS_I2C3 FALSE +#define STM32_I2C3_RX_DMA_MSK 0 +#define STM32_I2C3_RX_DMA_CHN 0x00000000 +#define STM32_I2C3_TX_DMA_MSK 0 +#define STM32_I2C3_TX_DMA_CHN 0x00000000 /* RTC attributes.*/ -#define STM32_HAS_RTC TRUE -#define STM32_RTC_HAS_SUBSECONDS TRUE -#define STM32_RTC_IS_CALENDAR TRUE +#define STM32_HAS_RTC TRUE +#define STM32_RTC_HAS_SUBSECONDS TRUE +#define STM32_RTC_IS_CALENDAR TRUE /* SDIO attributes.*/ -#define STM32_HAS_SDIO FALSE +#define STM32_HAS_SDIO FALSE /* SPI attributes.*/ -#define STM32_HAS_SPI1 TRUE -#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) -#define STM32_SPI1_RX_DMA_CHN 0x00000000 -#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) -#define STM32_SPI1_TX_DMA_CHN 0x00000000 +#define STM32_HAS_SPI1 TRUE +#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) -#define STM32_HAS_SPI2 TRUE -#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) -#define STM32_SPI2_RX_DMA_CHN 0x00000000 -#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) -#define STM32_SPI2_TX_DMA_CHN 0x00000000 +#define STM32_HAS_SPI2 TRUE +#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) -#define STM32_HAS_SPI3 TRUE -#define STM32_SPI3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 1) -#define STM32_SPI3_RX_DMA_CHN 0x00000000 -#define STM32_SPI3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 2) -#define STM32_SPI3_TX_DMA_CHN 0x00000000 +#define STM32_HAS_SPI3 TRUE +#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) /* TIM attributes.*/ -#define STM32_TIM_MAX_CHANNELS 6 +#define STM32_TIM_MAX_CHANNELS 6 -#define STM32_HAS_TIM1 TRUE -#define STM32_TIM1_IS_32BITS FALSE -#define STM32_TIM1_CHANNELS 6 +#define STM32_HAS_TIM1 TRUE +#define STM32_TIM1_IS_32BITS FALSE +#define STM32_TIM1_CHANNELS 6 -#define STM32_HAS_TIM2 TRUE -#define STM32_TIM2_IS_32BITS TRUE -#define STM32_TIM2_CHANNELS 4 +#define STM32_HAS_TIM2 TRUE +#define STM32_TIM2_IS_32BITS TRUE +#define STM32_TIM2_CHANNELS 4 -#define STM32_HAS_TIM3 TRUE -#define STM32_TIM3_IS_32BITS FALSE -#define STM32_TIM3_CHANNELS 4 +#define STM32_HAS_TIM3 TRUE +#define STM32_TIM3_IS_32BITS FALSE +#define STM32_TIM3_CHANNELS 4 -#define STM32_HAS_TIM4 TRUE -#define STM32_TIM4_IS_32BITS FALSE -#define STM32_TIM4_CHANNELS 4 +#define STM32_HAS_TIM4 TRUE +#define STM32_TIM4_IS_32BITS FALSE +#define STM32_TIM4_CHANNELS 4 -#define STM32_HAS_TIM6 TRUE -#define STM32_TIM6_IS_32BITS FALSE -#define STM32_TIM6_CHANNELS 0 +#define STM32_HAS_TIM6 TRUE +#define STM32_TIM6_IS_32BITS FALSE +#define STM32_TIM6_CHANNELS 0 -#define STM32_HAS_TIM7 TRUE -#define STM32_TIM7_IS_32BITS FALSE -#define STM32_TIM7_CHANNELS 0 +#define STM32_HAS_TIM7 TRUE +#define STM32_TIM7_IS_32BITS FALSE +#define STM32_TIM7_CHANNELS 0 -#define STM32_HAS_TIM8 TRUE -#define STM32_TIM8_IS_32BITS FALSE -#define STM32_TIM8_CHANNELS 6 +#define STM32_HAS_TIM8 TRUE +#define STM32_TIM8_IS_32BITS FALSE +#define STM32_TIM8_CHANNELS 6 -#define STM32_HAS_TIM15 TRUE -#define STM32_TIM15_IS_32BITS FALSE -#define STM32_TIM15_CHANNELS 2 +#define STM32_HAS_TIM15 TRUE +#define STM32_TIM15_IS_32BITS FALSE +#define STM32_TIM15_CHANNELS 2 -#define STM32_HAS_TIM16 TRUE -#define STM32_TIM16_IS_32BITS FALSE -#define STM32_TIM16_CHANNELS 2 +#define STM32_HAS_TIM16 TRUE +#define STM32_TIM16_IS_32BITS FALSE +#define STM32_TIM16_CHANNELS 2 -#define STM32_HAS_TIM17 TRUE -#define STM32_TIM17_IS_32BITS FALSE -#define STM32_TIM17_CHANNELS 2 +#define STM32_HAS_TIM17 TRUE +#define STM32_TIM17_IS_32BITS FALSE +#define STM32_TIM17_CHANNELS 2 -#define STM32_HAS_TIM5 FALSE -#define STM32_HAS_TIM9 FALSE -#define STM32_HAS_TIM10 FALSE -#define STM32_HAS_TIM11 FALSE -#define STM32_HAS_TIM12 FALSE -#define STM32_HAS_TIM13 FALSE -#define STM32_HAS_TIM14 FALSE -#define STM32_HAS_TIM18 FALSE -#define STM32_HAS_TIM19 FALSE +#define STM32_HAS_TIM5 FALSE +#define STM32_HAS_TIM9 FALSE +#define STM32_HAS_TIM10 FALSE +#define STM32_HAS_TIM11 FALSE +#define STM32_HAS_TIM12 FALSE +#define STM32_HAS_TIM13 FALSE +#define STM32_HAS_TIM14 FALSE +#define STM32_HAS_TIM18 FALSE +#define STM32_HAS_TIM19 FALSE /* USART attributes.*/ -#define STM32_HAS_USART1 TRUE -#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) -#define STM32_USART1_RX_DMA_CHN 0x00000000 -#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)) -#define STM32_USART1_TX_DMA_CHN 0x00000000 +#define STM32_HAS_USART1 TRUE +#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) -#define STM32_HAS_USART2 TRUE -#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) -#define STM32_USART2_RX_DMA_CHN 0x00000000 -#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) -#define STM32_USART2_TX_DMA_CHN 0x00000000 +#define STM32_HAS_USART2 TRUE +#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) -#define STM32_HAS_USART3 TRUE -#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)) -#define STM32_USART3_RX_DMA_CHN 0x00000000 -#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2)) -#define STM32_USART3_TX_DMA_CHN 0x00000000 +#define STM32_HAS_USART3 TRUE +#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) -#define STM32_HAS_UART4 TRUE -#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3)) -#define STM32_UART4_RX_DMA_CHN 0x00000000 -#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5)) -#define STM32_UART4_TX_DMA_CHN 0x00000000 +#define STM32_HAS_UART4 TRUE +#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) -#define STM32_HAS_UART5 TRUE -#define STM32_UART5_RX_DMA_MSK 0 -#define STM32_UART5_RX_DMA_CHN 0x00000000 -#define STM32_UART5_TX_DMA_MSK 0 -#define STM32_UART5_TX_DMA_CHN 0x00000000 +#define STM32_HAS_UART5 TRUE -#define STM32_HAS_USART6 FALSE -#define STM32_USART6_RX_DMA_MSK 0 -#define STM32_USART6_RX_DMA_CHN 0x00000000 -#define STM32_USART6_TX_DMA_MSK 0 -#define STM32_USART6_TX_DMA_CHN 0x00000000 +#define STM32_HAS_USART6 FALSE /* USB attributes.*/ -#define STM32_HAS_USB TRUE -#define STM32_HAS_OTG1 FALSE -#define STM32_HAS_OTG2 FALSE +#define STM32_HAS_USB TRUE +#define STM32_HAS_OTG1 FALSE +#define STM32_HAS_OTG2 FALSE /** @} */ #endif /* _STM32_REGISTRY_H_ */ diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c new file mode 100644 index 000000000..3e037332b --- /dev/null +++ b/os/hal/src/i2c.c @@ -0,0 +1,283 @@ +/* + 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 . +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file i2c.c + * @brief I2C Driver code. + * + * @addtogroup I2C + * @{ + */ +#include "hal.h" + +#if HAL_USE_I2C || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief I2C Driver initialization. + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. + * + * @init + */ +void i2cInit(void) { + + i2c_lld_init(); +} + +/** + * @brief Initializes the standard part of a @p I2CDriver structure. + * + * @param[out] i2cp pointer to the @p I2CDriver object + * + * @init + */ +void i2cObjectInit(I2CDriver *i2cp) { + + i2cp->state = I2C_STOP; + i2cp->config = NULL; + +#if I2C_USE_MUTUAL_EXCLUSION + osalMutexObjectInit(&i2cp->mutex); +#endif /* I2C_USE_MUTUAL_EXCLUSION */ + +#if defined(I2C_DRIVER_EXT_INIT_HOOK) + I2C_DRIVER_EXT_INIT_HOOK(i2cp); +#endif +} + +/** + * @brief Configures and activates the I2C peripheral. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] config pointer to the @p I2CConfig object + * + * @api + */ +void i2cStart(I2CDriver *i2cp, const I2CConfig *config) { + + osalDbgCheck((i2cp != NULL) && (config != NULL)); + osalDbgAssert((i2cp->state == I2C_STOP) || (i2cp->state == I2C_READY) || + (i2cp->state == I2C_LOCKED), "invalid state"); + + osalSysLock(); + i2cp->config = config; + i2c_lld_start(i2cp); + i2cp->state = I2C_READY; + osalSysUnlock(); +} + +/** + * @brief Deactivates the I2C peripheral. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @api + */ +void i2cStop(I2CDriver *i2cp) { + + osalDbgCheck(i2cp != NULL); + osalDbgAssert((i2cp->state == I2C_STOP) || (i2cp->state == I2C_READY) || + (i2cp->state == I2C_LOCKED), "invalid state"); + + osalSysLock(); + i2c_lld_stop(i2cp); + i2cp->state = I2C_STOP; + osalSysUnlock(); +} + +/** + * @brief Returns the errors mask associated to the previous operation. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @return The errors mask. + * + * @api + */ +i2cflags_t i2cGetErrors(I2CDriver *i2cp) { + + osalDbgCheck(i2cp != NULL); + + return i2c_lld_get_errors(i2cp); +} + +/** + * @brief Sends data via the I2C bus. + * @details Function designed to realize "read-through-write" transfer + * paradigm. If you want transmit data without any further read, + * than set @b rxbytes field to 0. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] addr slave device address (7 bits) without R/W bit + * @param[in] txbuf pointer to transmit buffer + * @param[in] txbytes number of bytes to be transmitted + * @param[out] rxbuf pointer to receive buffer + * @param[in] rxbytes number of bytes to be received, set it to 0 if + * you want transmit only + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_INFINITE no timeout. + * . + * + * @return The operation status. + * @retval MSG_OK if the function succeeded. + * @retval MSG_RESET if one or more I2C errors occurred, the errors can + * be retrieved using @p i2cGetErrors(). + * @retval MSG_TIMEOUT if a timeout occurred before operation end. + * + * @api + */ +msg_t i2cMasterTransmitTimeout(I2CDriver *i2cp, + i2caddr_t addr, + const uint8_t *txbuf, + size_t txbytes, + uint8_t *rxbuf, + size_t rxbytes, + systime_t timeout) { + msg_t rdymsg; + + osalDbgCheck((i2cp != NULL) && (addr != 0) && + (txbytes > 0) && (txbuf != NULL) && + ((rxbytes == 0) || ((rxbytes > 0) && (rxbuf != NULL))) && + (timeout != TIME_IMMEDIATE)); + + osalDbgAssert(i2cp->state == I2C_READY, "not ready"); + + osalSysLock(); + i2cp->errors = I2C_NO_ERROR; + i2cp->state = I2C_ACTIVE_TX; + rdymsg = i2c_lld_master_transmit_timeout(i2cp, addr, txbuf, txbytes, + rxbuf, rxbytes, timeout); + if (rdymsg == MSG_TIMEOUT) + i2cp->state = I2C_LOCKED; + else + i2cp->state = I2C_READY; + osalSysUnlock(); + return rdymsg; +} + +/** + * @brief Receives data from the I2C bus. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] addr slave device address (7 bits) without R/W bit + * @param[out] rxbuf pointer to receive buffer + * @param[in] rxbytes number of bytes to be received + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_INFINITE no timeout. + * . + * + * @return The operation status. + * @retval MSG_OK if the function succeeded. + * @retval MSG_RESET if one or more I2C errors occurred, the errors can + * be retrieved using @p i2cGetErrors(). + * @retval MSG_TIMEOUT if a timeout occurred before operation end. + * + * @api + */ +msg_t i2cMasterReceiveTimeout(I2CDriver *i2cp, + i2caddr_t addr, + uint8_t *rxbuf, + size_t rxbytes, + systime_t timeout){ + + msg_t rdymsg; + + osalDbgCheck((i2cp != NULL) && (addr != 0) && + (rxbytes > 0) && (rxbuf != NULL) && + (timeout != TIME_IMMEDIATE)); + + osalDbgAssert(i2cp->state == I2C_READY, "not ready"); + + osalSysLock(); + i2cp->errors = I2C_NO_ERROR; + i2cp->state = I2C_ACTIVE_RX; + rdymsg = i2c_lld_master_receive_timeout(i2cp, addr, rxbuf, rxbytes, timeout); + if (rdymsg == MSG_TIMEOUT) + i2cp->state = I2C_LOCKED; + else + i2cp->state = I2C_READY; + osalSysUnlock(); + return rdymsg; +} + +#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) +/** + * @brief Gains exclusive access to the I2C bus. + * @details This function tries to gain ownership to the SPI bus, if the bus + * is already being used then the invoking thread is queued. + * @pre In order to use this function the option @p I2C_USE_MUTUAL_EXCLUSION + * must be enabled. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @api + */ +void i2cAcquireBus(I2CDriver *i2cp) { + + osalDbgCheck(i2cp != NULL); + + osalMutexLock(&i2cp->mutex); +} + +/** + * @brief Releases exclusive access to the I2C bus. + * @pre In order to use this function the option @p I2C_USE_MUTUAL_EXCLUSION + * must be enabled. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @api + */ +void i2cReleaseBus(I2CDriver *i2cp) { + + osalDbgCheck(i2cp != NULL); + + osalMutexUnlock(&i2cp->mutex); +} +#endif /* I2C_USE_MUTUAL_EXCLUSION */ + +#endif /* HAL_USE_I2C */ + +/** @} */