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-d51de3d6d3f4master
parent
155ef8ed75
commit
dbd493cff1
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
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_ */
|
||||
|
||||
/** @} */
|
|
@ -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. <b>After a
|
||||
* @retval MSG_TIMEOUT if a timeout occurred before operation end. <b>After a
|
||||
* timeout the driver must be stopped and restarted
|
||||
* because the bus is in an uncertain state</b>.
|
||||
*
|
||||
|
@ -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. <b>After a
|
||||
* @retval MSG_TIMEOUT if a timeout occurred before operation end. <b>After a
|
||||
* timeout the driver must be stopped and restarted
|
||||
* because the bus is in an uncertain state</b>.
|
||||
*
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
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 */
|
||||
|
||||
/** @} */
|
Loading…
Reference in New Issue