I2C. Merge code to trunk.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3576 35acf78f-673a-0410-8e92-d51de3d6d3f4master
commit
87ea7c6eec
|
@ -87,67 +87,15 @@ typedef enum {
|
||||||
I2C_READY = 2, /**< Ready. */
|
I2C_READY = 2, /**< Ready. */
|
||||||
I2C_ACTIVE_TRANSMIT = 3, /**< Transmitting. */
|
I2C_ACTIVE_TRANSMIT = 3, /**< Transmitting. */
|
||||||
I2C_ACTIVE_RECEIVE = 4, /**< Receiving. */
|
I2C_ACTIVE_RECEIVE = 4, /**< Receiving. */
|
||||||
I2C_ACTIVE_TRANSCEIVE = 5, /**< Receiving after transmit. */
|
|
||||||
} i2cstate_t;
|
} i2cstate_t;
|
||||||
|
|
||||||
#include "i2c_lld.h"
|
#include "i2c_lld.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief I2C notification callback type.
|
|
||||||
* @details This callback invoked when byte transfer finish event occurs,
|
|
||||||
* no matter if sending or reading.
|
|
||||||
*
|
|
||||||
* @param[in] i2cp pointer to the @p I2CDriver object triggering the
|
|
||||||
* callback
|
|
||||||
* @param[in] i2cscfg pointer to the @p I2CSlaveConfig object triggering the
|
|
||||||
* callback
|
|
||||||
*/
|
|
||||||
typedef void (*i2ccallback_t)(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief I2C error notification callback type.
|
|
||||||
*
|
|
||||||
* @param[in] i2cp pointer to the @p I2CDriver object triggering the
|
|
||||||
* callback
|
|
||||||
* @param[in] i2cscfg pointer to the @p I2CSlaveConfig object triggering the
|
|
||||||
* callback
|
|
||||||
*/
|
|
||||||
typedef void (*i2cerrorcallback_t)(I2CDriver *i2cp,
|
|
||||||
const I2CSlaveConfig *i2cscfg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief I2C transmission data block size.
|
|
||||||
*/
|
|
||||||
typedef uint8_t i2cblock_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Structure representing an I2C slave configuration.
|
|
||||||
* @details Each slave device has its own config structure with input and
|
|
||||||
* output buffers for temporally storing data.
|
|
||||||
*/
|
|
||||||
struct I2CSlaveConfig{
|
|
||||||
/**
|
|
||||||
* @brief Callback pointer.
|
|
||||||
* @note Transfer finished callback. Invoke when all data transferred.
|
|
||||||
* If set to @p NULL then the callback is disabled.
|
|
||||||
*/
|
|
||||||
i2ccallback_t id_callback;
|
|
||||||
/**
|
|
||||||
* @brief Callback pointer.
|
|
||||||
* @note This callback will be invoked when error condition occur.
|
|
||||||
* If set to @p NULL then the callback is disabled.
|
|
||||||
*/
|
|
||||||
i2cerrorcallback_t id_err_callback;
|
|
||||||
#if defined(I2C_SLAVECONFIG_EXT_FIELDS)
|
|
||||||
I2C_SLAVECONFIG_EXT_FIELDS
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver macros. */
|
/* Driver macros. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
#if I2C_USE_WAIT || defined(__DOXYGEN__)
|
|
||||||
/**
|
/**
|
||||||
* @brief Waits for operation completion.
|
* @brief Waits for operation completion.
|
||||||
* @details This function waits for the driver to complete the current
|
* @details This function waits for the driver to complete the current
|
||||||
|
@ -185,58 +133,40 @@ struct I2CSlaveConfig{
|
||||||
chSysUnlockFromIsr(); \
|
chSysUnlockFromIsr(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
#else /* !I2C_USE_WAIT */
|
|
||||||
#define _i2c_wait_s(i2cp)
|
|
||||||
#define _i2c_wakeup_isr(i2cp)
|
|
||||||
#endif /* !I2C_USE_WAIT */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Common ISR code.
|
* @brief Common ISR code.
|
||||||
* @details This code handles the portable part of the ISR code:
|
* @details This code handles the portable part of the ISR code:
|
||||||
* - Callback invocation.
|
* - Waiting thread wakeup.
|
||||||
* - Waiting thread wakeup, if any.
|
|
||||||
* - Driver state transitions.
|
* - Driver state transitions.
|
||||||
*
|
*
|
||||||
* @note This macro is meant to be used in the low level drivers
|
* @note This macro is meant to be used in the low level drivers
|
||||||
* implementation only.
|
* implementation only.
|
||||||
*
|
*
|
||||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||||
* @param[in] i2cscfg pointer to the @p I2CSlaveConfig object
|
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
#define _i2c_isr_code(i2cp, i2cscfg) { \
|
#define _i2c_isr_code(i2cp, i2cscfg) { \
|
||||||
if(((i2cp)->id_slave_config)->id_callback) { \
|
(i2cp)->id_state = I2C_READY; \
|
||||||
((i2cp)->id_slave_config)->id_callback(i2cp, i2cscfg); \
|
|
||||||
(i2cp)->id_state = I2C_READY; \
|
|
||||||
} \
|
|
||||||
else \
|
|
||||||
(i2cp)->id_state = I2C_READY; \
|
|
||||||
_i2c_wakeup_isr(i2cp); \
|
_i2c_wakeup_isr(i2cp); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Error ISR code.
|
* @brief Error ISR code.
|
||||||
* @details This code handles the portable part of the ISR code:
|
* @details This code handles the portable part of the ISR code:
|
||||||
* - Error callback invocation.
|
* - Waiting thread wakeup.
|
||||||
* - Waiting thread wakeup, if any.
|
|
||||||
* - Driver state transitions.
|
* - Driver state transitions.
|
||||||
*
|
*
|
||||||
* @note This macro is meant to be used in the low level drivers
|
* @note This macro is meant to be used in the low level drivers
|
||||||
* implementation only.
|
* implementation only.
|
||||||
*
|
*
|
||||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||||
* @param[in] i2cscfg pointer to the @p I2CSlaveConfig object
|
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
#define _i2c_isr_err_code(i2cp, i2cscfg) { \
|
#define _i2c_isr_err_code(i2cp, i2cscfg) { \
|
||||||
if(((i2cp)->id_slave_config)->id_err_callback) { \
|
(i2cp)->id_state = I2C_READY; \
|
||||||
((i2cp)->id_slave_config)->id_err_callback(i2cp, i2cscfg); \
|
|
||||||
(i2cp)->id_state = I2C_READY; \
|
|
||||||
} \
|
|
||||||
else \
|
|
||||||
(i2cp)->id_state = I2C_READY; \
|
|
||||||
_i2c_wakeup_isr(i2cp); \
|
_i2c_wakeup_isr(i2cp); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,15 +181,16 @@ extern "C" {
|
||||||
void i2cObjectInit(I2CDriver *i2cp);
|
void i2cObjectInit(I2CDriver *i2cp);
|
||||||
void i2cStart(I2CDriver *i2cp, const I2CConfig *config);
|
void i2cStart(I2CDriver *i2cp, const I2CConfig *config);
|
||||||
void i2cStop(I2CDriver *i2cp);
|
void i2cStop(I2CDriver *i2cp);
|
||||||
void i2cMasterTransmit(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg,
|
i2cflags_t i2cMasterTransmit(I2CDriver *i2cp,
|
||||||
uint16_t slave_addr,
|
uint8_t slave_addr,
|
||||||
uint8_t *txbuf, size_t txbytes,
|
uint8_t *txbuf, size_t txbytes,
|
||||||
uint8_t *rxbuf, size_t rxbytes);
|
uint8_t *rxbuf, size_t rxbytes);
|
||||||
void i2cMasterReceive(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg,
|
i2cflags_t i2cMasterReceive(I2CDriver *i2cp,
|
||||||
uint16_t slave_addr, uint8_t *rxbuf, size_t rxbytes);
|
uint8_t slave_addr, uint8_t *rxbuf, size_t rxbytes);
|
||||||
void i2cMasterStart(I2CDriver *i2cp);
|
void i2cMasterStart(I2CDriver *i2cp);
|
||||||
void i2cMasterStop(I2CDriver *i2cp);
|
void i2cMasterStop(I2CDriver *i2cp);
|
||||||
void i2cAddFlagsI(I2CDriver *i2cp, i2cflags_t mask);
|
void i2cAddFlagsI(I2CDriver *i2cp, i2cflags_t mask);
|
||||||
|
i2cflags_t i2cGetAndClearFlags(I2CDriver *i2cp);
|
||||||
|
|
||||||
#if I2C_USE_MUTUAL_EXCLUSION
|
#if I2C_USE_MUTUAL_EXCLUSION
|
||||||
void i2cAcquireBus(I2CDriver *i2cp);
|
void i2cAcquireBus(I2CDriver *i2cp);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,318 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||||
|
2011 Giovanni Di Sirio.
|
||||||
|
|
||||||
|
This file is part of ChibiOS/RT.
|
||||||
|
|
||||||
|
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file STM32/i2c_lld.h
|
||||||
|
* @brief STM32 I2C subsystem low level driver header.
|
||||||
|
* @addtogroup I2C
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _I2C_LLD_H_
|
||||||
|
#define _I2C_LLD_H_
|
||||||
|
|
||||||
|
#if HAL_USE_I2C || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Configuration options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief Switch between callback based and synchronouse driver.
|
||||||
|
* @note The default is synchronouse.
|
||||||
|
*/
|
||||||
|
#if !defined(I2C_SUPPORTS_CALLBACKS) || defined(__DOXYGEN__)
|
||||||
|
#define I2C_SUPPORTS_CALLBACKS TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2C1 driver synchronization choice between GPT and polling.
|
||||||
|
* @note The default is polling wait.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_I2C1_USE_GPT_TIM) || \
|
||||||
|
!defined(STM32_I2C_I2C1_USE_POLLING_WAIT) || \
|
||||||
|
defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_I2C1_USE_POLLING_WAIT TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2C2 driver synchronization choice between GPT and polling.
|
||||||
|
* @note The default is polling wait.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_I2C2_USE_GPT_TIM) || \
|
||||||
|
!defined(STM32_I2C_I2C2_USE_POLLING_WAIT) || \
|
||||||
|
defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_I2C2_USE_POLLING_WAIT TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2C1 driver enable switch.
|
||||||
|
* @details If set to @p TRUE the support for I2C1 is included.
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_USE_I2C1) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_USE_I2C1 TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2C2 driver enable switch.
|
||||||
|
* @details If set to @p TRUE the support for I2C2 is included.
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_USE_I2C2) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_USE_I2C2 TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2C1 interrupt priority level setting.
|
||||||
|
* @note @p BASEPRI_KERNEL >= @p STM32_I2C_I2C1_IRQ_PRIORITY > @p PRIORITY_PENDSV.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_I2C1_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_I2C1_IRQ_PRIORITY 0xA0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2C2 interrupt priority level setting.
|
||||||
|
* @note @p BASEPRI_KERNEL >= @p STM32_I2C_I2C2_IRQ_PRIORITY > @p PRIORITY_PENDSV.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_I2C2_IRQ_PRIORITY 0xA0
|
||||||
|
#endif
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/** @brief EV5 */
|
||||||
|
#define I2C_EV5_MASTER_MODE_SELECT ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_SB)) /* BUSY, MSL and SB flag */
|
||||||
|
/** @brief EV6 */
|
||||||
|
#define I2C_EV6_MASTER_TRA_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_ADDR|I2C_SR1_TXE)) /* BUSY, MSL, ADDR, TXE and TRA flags */
|
||||||
|
#define I2C_EV6_MASTER_REC_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_ADDR)) /* BUSY, MSL and ADDR flags */
|
||||||
|
/** @brief EV7 */
|
||||||
|
#define I2C_EV7_MASTER_REC_BYTE_RECEIVED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_RXNE)) /* BUSY, MSL and RXNE flags */
|
||||||
|
#define I2C_EV7_MASTER_REC_BYTE_QUEUED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_BTF|I2C_SR1_RXNE)) /* BUSY, MSL, RXNE and BTF flags*/
|
||||||
|
/** @brief EV8 */
|
||||||
|
#define I2C_EV8_MASTER_BYTE_TRANSMITTING ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE flags */
|
||||||
|
/** @brief EV8_2 */
|
||||||
|
#define I2C_EV8_2_MASTER_BYTE_TRANSMITTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_BTF|I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE and BTF flags */
|
||||||
|
/** @brief EV9 */
|
||||||
|
#define I2C_EV9_MASTER_ADDR_10BIT ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_ADD10)) /* BUSY, MSL and ADD10 flags */
|
||||||
|
#define I2C_EV_MASK 0x00FFFFFF /* First byte zeroed because there is no need of PEC register part from SR2 */
|
||||||
|
|
||||||
|
#define I2C_FLG_1BTR 0x01 /* Single byte to be received and processed */
|
||||||
|
#define I2C_FLG_2BTR 0x02 /* Two bytes to be received and processed */
|
||||||
|
#define I2C_FLG_3BTR 0x04 /* Last three received bytes to be processed */
|
||||||
|
#define I2C_FLG_MASTER_RECEIVER 0x10
|
||||||
|
#define I2C_FLG_HEADER_SENT 0x80
|
||||||
|
#define I2C_FLG_TIMER_ARMED 0x40 /* Used to check locks on the bus */
|
||||||
|
|
||||||
|
#define EV6_SUBEV_MASK (I2C_FLG_1BTR|I2C_FLG_2BTR|I2C_FLG_MASTER_RECEIVER)
|
||||||
|
#define EV7_SUBEV_MASK (I2C_FLG_2BTR|I2C_FLG_3BTR|I2C_FLG_MASTER_RECEIVER)
|
||||||
|
|
||||||
|
#define I2C_EV6_1_MASTER_REC_2BTR_MODE_SELECTED (I2C_FLG_2BTR|I2C_FLG_MASTER_RECEIVER)
|
||||||
|
#define I2C_EV6_3_MASTER_REC_1BTR_MODE_SELECTED (I2C_FLG_1BTR|I2C_FLG_MASTER_RECEIVER)
|
||||||
|
#define I2C_EV7_2_MASTER_REC_3BYTES_TO_PROCESS (I2C_FLG_3BTR|I2C_FLG_MASTER_RECEIVER)
|
||||||
|
#define I2C_EV7_3_MASTER_REC_2BYTES_TO_PROCESS (I2C_FLG_2BTR|I2C_FLG_MASTER_RECEIVER)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2C Driver condition flags type.
|
||||||
|
*/
|
||||||
|
typedef uint32_t i2cflags_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OPMODE_I2C = 1,
|
||||||
|
OPMODE_SMBUS_DEVICE = 2,
|
||||||
|
OPMODE_SMBUS_HOST = 3,
|
||||||
|
} i2copmode_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
STD_DUTY_CYCLE = 1,
|
||||||
|
FAST_DUTY_CYCLE_2 = 2,
|
||||||
|
FAST_DUTY_CYCLE_16_9 = 3,
|
||||||
|
} i2cdutycycle_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Driver configuration structure.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
i2copmode_t op_mode; /**< @brief Specifies the I2C mode.*/
|
||||||
|
uint32_t clock_speed; /**< @brief Specifies the clock frequency. Must be set to a value lower than 400kHz */
|
||||||
|
i2cdutycycle_t duty_cycle; /**< @brief Specifies the I2C fast mode duty cycle */
|
||||||
|
uint8_t own_addr_7; /**< @brief Specifies the first device 7-bit own address. */
|
||||||
|
uint16_t own_addr_10; /**< @brief Specifies the second part of device own address in 10-bit mode. Set to NULL if not used. */
|
||||||
|
uint8_t nbit_own_addr; /**< @brief Specifies if 7-bit or 10-bit address is acknowledged */
|
||||||
|
} I2CConfig;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of a structure representing an I2C driver.
|
||||||
|
*/
|
||||||
|
typedef struct I2CDriver I2CDriver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of a structure representing an I2C slave config.
|
||||||
|
*/
|
||||||
|
typedef struct I2CSlaveConfig I2CSlaveConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure representing an I2C driver.
|
||||||
|
*/
|
||||||
|
struct I2CDriver{
|
||||||
|
/**
|
||||||
|
* @brief Driver state.
|
||||||
|
*/
|
||||||
|
i2cstate_t id_state;
|
||||||
|
|
||||||
|
#if I2C_USE_WAIT
|
||||||
|
/**
|
||||||
|
* @brief Thread waiting for I/O completion.
|
||||||
|
*/
|
||||||
|
Thread *id_thread;
|
||||||
|
#endif /* I2C_USE_WAIT */
|
||||||
|
#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
|
||||||
|
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Mutex protecting the bus.
|
||||||
|
*/
|
||||||
|
Mutex id_mutex;
|
||||||
|
#elif CH_USE_SEMAPHORES
|
||||||
|
Semaphore id_semaphore;
|
||||||
|
#endif
|
||||||
|
#endif /* I2C_USE_MUTUAL_EXCLUSION */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Current configuration data.
|
||||||
|
*/
|
||||||
|
const I2CConfig *id_config;
|
||||||
|
/**
|
||||||
|
* @brief Current slave configuration data.
|
||||||
|
*/
|
||||||
|
const I2CSlaveConfig *id_slave_config;
|
||||||
|
|
||||||
|
__IO size_t txbytes; /*!< @brief Number of bytes to be transmitted. */
|
||||||
|
__IO size_t rxbytes; /*!< @brief Number of bytes to be received. */
|
||||||
|
uint8_t *rxbuf; /*!< @brief Pointer to receive buffer. */
|
||||||
|
uint8_t *txbuf; /*!< @brief Pointer to transmit buffer.*/
|
||||||
|
uint8_t *rxbuff_p; /*!< @brief Pointer to the current byte in slave rx buffer. */
|
||||||
|
uint8_t *txbuff_p; /*!< @brief Pointer to the current byte in slave tx buffer. */
|
||||||
|
|
||||||
|
__IO i2cflags_t errors; /*!< @brief Error flags.*/
|
||||||
|
__IO i2cflags_t flags; /*!< @brief State flags.*/
|
||||||
|
|
||||||
|
uint16_t slave_addr; /*!< @brief Current slave address. */
|
||||||
|
uint8_t slave_addr1;/*!< @brief 7-bit address of the slave with r\w bit.*/
|
||||||
|
uint8_t slave_addr2;/*!< @brief Uses in 10-bit address mode. */
|
||||||
|
|
||||||
|
#if CH_USE_EVENTS
|
||||||
|
EventSource sevent; /*!< @brief Status Change @p EventSource.*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********** End of the mandatory fields. **********************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pointer to the I2Cx registers block.
|
||||||
|
*/
|
||||||
|
I2C_TypeDef *id_i2c;
|
||||||
|
|
||||||
|
#if !(STM32_I2C_I2C1_USE_POLLING_WAIT)
|
||||||
|
/* TODO: capability to switch this GPT fields off */
|
||||||
|
/**
|
||||||
|
* @brief Timer for waiting STOP condition on the bus.
|
||||||
|
* @details This is workaround for STM32 buggy I2C cell.
|
||||||
|
*/
|
||||||
|
GPTDriver *timer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Config for workaround timer.
|
||||||
|
*/
|
||||||
|
const GPTConfig *timer_cfg;
|
||||||
|
#endif /* !(STM32_I2C_I2C1_USE_POLLING_WAIT) */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define i2c_lld_bus_is_busy(i2cp) \
|
||||||
|
(i2cp->id_i2c->SR2 & I2C_SR2_BUSY)
|
||||||
|
|
||||||
|
|
||||||
|
/* Wait until BUSY flag is reset: a STOP has been generated on the bus
|
||||||
|
* signaling the end of transmission. Normally this wait function
|
||||||
|
* does not block thread, only if slave not response it does.
|
||||||
|
*/
|
||||||
|
#define i2c_lld_wait_bus_free(i2cp) { \
|
||||||
|
uint32_t tmo = 0xfffff; \
|
||||||
|
while((i2cp->id_i2c->SR2 & I2C_SR2_BUSY) && tmo--) \
|
||||||
|
; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/** @cond never*/
|
||||||
|
#if STM32_I2C_USE_I2C1
|
||||||
|
extern I2CDriver I2CD1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STM32_I2C_USE_I2C2
|
||||||
|
extern I2CDriver I2CD2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void i2c_lld_init(void);
|
||||||
|
void i2c_lld_reset(I2CDriver *i2cp);
|
||||||
|
void i2c_lld_set_clock(I2CDriver *i2cp);
|
||||||
|
void i2c_lld_set_opmode(I2CDriver *i2cp);
|
||||||
|
void i2c_lld_set_own_address(I2CDriver *i2cp);
|
||||||
|
void i2c_lld_start(I2CDriver *i2cp);
|
||||||
|
void i2c_lld_stop(I2CDriver *i2cp);
|
||||||
|
void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr,
|
||||||
|
uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes);
|
||||||
|
void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr,
|
||||||
|
uint8_t *rxbuf, size_t rxbytes);
|
||||||
|
void i2c_lld_master_transceive(I2CDriver *i2cp);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/** @endcond*/
|
||||||
|
|
||||||
|
#endif /* CH_HAL_USE_I2C */
|
||||||
|
|
||||||
|
#endif /* _I2C_LLD_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -42,50 +42,32 @@
|
||||||
* @name Configuration options
|
* @name Configuration options
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* @brief Switch between callback based and synchronouse driver.
|
|
||||||
* @note The default is synchronouse.
|
|
||||||
*/
|
|
||||||
#if !defined(I2C_SUPPORTS_CALLBACKS) || defined(__DOXYGEN__)
|
|
||||||
#define I2C_SUPPORTS_CALLBACKS TRUE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief I2C1 driver synchronization choice between GPT and polling.
|
|
||||||
* @note The default is polling wait.
|
|
||||||
*/
|
|
||||||
#if !defined(STM32_I2C_I2C1_USE_GPT_TIM) || \
|
|
||||||
!defined(STM32_I2C_I2C1_USE_POLLING_WAIT) || \
|
|
||||||
defined(__DOXYGEN__)
|
|
||||||
#define STM32_I2C_I2C1_USE_POLLING_WAIT TRUE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief I2C2 driver synchronization choice between GPT and polling.
|
|
||||||
* @note The default is polling wait.
|
|
||||||
*/
|
|
||||||
#if !defined(STM32_I2C_I2C2_USE_GPT_TIM) || \
|
|
||||||
!defined(STM32_I2C_I2C2_USE_POLLING_WAIT) || \
|
|
||||||
defined(__DOXYGEN__)
|
|
||||||
#define STM32_I2C_I2C2_USE_POLLING_WAIT TRUE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief I2C1 driver enable switch.
|
* @brief I2C1 driver enable switch.
|
||||||
* @details If set to @p TRUE the support for I2C1 is included.
|
* @details If set to @p TRUE the support for I2C1 is included.
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(STM32_I2C_USE_I2C1) || defined(__DOXYGEN__)
|
#if !defined(STM32_I2C_USE_I2C1) || defined(__DOXYGEN__)
|
||||||
#define STM32_I2C_USE_I2C1 TRUE
|
#define STM32_I2C_USE_I2C1 FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief I2C2 driver enable switch.
|
* @brief I2C2 driver enable switch.
|
||||||
* @details If set to @p TRUE the support for I2C2 is included.
|
* @details If set to @p TRUE the support for I2C2 is included.
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(STM32_I2C_USE_I2C2) || defined(__DOXYGEN__)
|
#if !defined(STM32_I2C_USE_I2C2) || defined(__DOXYGEN__)
|
||||||
#define STM32_I2C_USE_I2C2 TRUE
|
#define STM32_I2C_USE_I2C2 FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2C3 driver enable switch.
|
||||||
|
* @details If set to @p TRUE the support for I2C3 is included.
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_USE_I2C3) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_USE_I2C3 FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,42 +85,157 @@
|
||||||
#if !defined(STM32_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
#if !defined(STM32_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||||
#define STM32_I2C_I2C2_IRQ_PRIORITY 0xA0
|
#define STM32_I2C_I2C2_IRQ_PRIORITY 0xA0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2C2 interrupt priority level setting.
|
||||||
|
* @note @p BASEPRI_KERNEL >= @p STM32_I2C_I2C2_IRQ_PRIORITY > @p PRIORITY_PENDSV.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_I2C3_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_I2C3_IRQ_PRIORITY 0xA0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2C1 DMA error hook.
|
||||||
|
* @note The default action for DMA errors is a system halt because DMA
|
||||||
|
* error can only happen because programming errors.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STM32_ADVANCED_DMA || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DMA stream used for I2C1 RX operations.
|
||||||
|
* @note This option is only available on platforms with enhanced DMA.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_I2C1_RX_DMA_STREAM) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DMA stream used for I2C1 TX operations.
|
||||||
|
* @note This option is only available on platforms with enhanced DMA.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_I2C1_TX_DMA_STREAM) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DMA stream used for I2C2 RX operations.
|
||||||
|
* @note This option is only available on platforms with enhanced DMA.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_I2C2_RX_DMA_STREAM) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DMA stream used for I2C2 TX operations.
|
||||||
|
* @note This option is only available on platforms with enhanced DMA.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_I2C2_TX_DMA_STREAM) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DMA stream used for I2C3 RX operations.
|
||||||
|
* @note This option is only available on platforms with enhanced DMA.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_I2C3_RX_DMA_STREAM) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DMA stream used for I2C3 TX operations.
|
||||||
|
* @note This option is only available on platforms with enhanced DMA.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_I2C3_TX_DMA_STREAM) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* !STM32_ADVANCED_DMA */
|
||||||
|
|
||||||
|
/* Fixed streams for platforms using the old DMA peripheral, the values are
|
||||||
|
valid for both STM32F1xx and STM32L1xx.*/
|
||||||
|
#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)
|
||||||
|
|
||||||
|
#endif /* !STM32_ADVANCED_DMA*/
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Derived constants and error checks. */
|
/* Derived constants and error checks. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/** @brief EV5 */
|
/** @brief flags for interrupt handling */
|
||||||
#define I2C_EV5_MASTER_MODE_SELECT ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_SB)) /* BUSY, MSL and SB flag */
|
#define I2C_EV5_MASTER_MODE_SELECT ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY) << 16) | I2C_SR1_SB)) /* BUSY, MSL and SB flag */
|
||||||
/** @brief EV6 */
|
|
||||||
#define I2C_EV6_MASTER_TRA_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_ADDR|I2C_SR1_TXE)) /* BUSY, MSL, ADDR, TXE and TRA flags */
|
#define I2C_EV6_MASTER_TRA_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_ADDR|I2C_SR1_TXE)) /* BUSY, MSL, ADDR, TXE and TRA flags */
|
||||||
#define I2C_EV6_MASTER_REC_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_ADDR)) /* BUSY, MSL and ADDR flags */
|
#define I2C_EV6_MASTER_REC_MODE_SELECTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_ADDR)) /* BUSY, MSL and ADDR flags */
|
||||||
/** @brief EV7 */
|
#define I2C_EV8_2_MASTER_BYTE_TRANSMITTED ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) | I2C_SR1_BTF | I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE and BTF flags */
|
||||||
#define I2C_EV7_MASTER_REC_BYTE_RECEIVED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_RXNE)) /* BUSY, MSL and RXNE flags */
|
|
||||||
#define I2C_EV7_MASTER_REC_BYTE_QUEUED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_BTF|I2C_SR1_RXNE)) /* BUSY, MSL, RXNE and BTF flags*/
|
|
||||||
/** @brief EV8 */
|
|
||||||
#define I2C_EV8_MASTER_BYTE_TRANSMITTING ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE flags */
|
|
||||||
/** @brief EV8_2 */
|
|
||||||
#define I2C_EV8_2_MASTER_BYTE_TRANSMITTED ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY|I2C_SR2_TRA)<< 16)|I2C_SR1_BTF|I2C_SR1_TXE)) /* TRA, BUSY, MSL, TXE and BTF flags */
|
|
||||||
/** @brief EV9 */
|
|
||||||
#define I2C_EV9_MASTER_ADDR_10BIT ((uint32_t)(((I2C_SR2_MSL|I2C_SR2_BUSY)<< 16)|I2C_SR1_ADD10)) /* BUSY, MSL and ADD10 flags */
|
|
||||||
#define I2C_EV_MASK 0x00FFFFFF /* First byte zeroed because there is no need of PEC register part from SR2 */
|
#define I2C_EV_MASK 0x00FFFFFF /* First byte zeroed because there is no need of PEC register part from SR2 */
|
||||||
|
|
||||||
#define I2C_FLG_1BTR 0x01 /* Single byte to be received and processed */
|
#define I2C_FLG_MASTER_RECEIVER 0x10
|
||||||
#define I2C_FLG_2BTR 0x02 /* Two bytes to be received and processed */
|
#define I2C_FLG_HEADER_SENT 0x80
|
||||||
#define I2C_FLG_3BTR 0x04 /* Last three received bytes to be processed */
|
|
||||||
#define I2C_FLG_MASTER_RECEIVER 0x10
|
|
||||||
#define I2C_FLG_HEADER_SENT 0x80
|
|
||||||
#define I2C_FLG_TIMER_ARMED 0x40 /* Used to check locks on the bus */
|
|
||||||
|
|
||||||
#define EV6_SUBEV_MASK (I2C_FLG_1BTR|I2C_FLG_2BTR|I2C_FLG_MASTER_RECEIVER)
|
/** @brief error checks */
|
||||||
#define EV7_SUBEV_MASK (I2C_FLG_2BTR|I2C_FLG_3BTR|I2C_FLG_MASTER_RECEIVER)
|
#if STM32_I2C_USE_I2C1 && !STM32_HAS_I2C1
|
||||||
|
#error "I2C1 not present in the selected device"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define I2C_EV6_1_MASTER_REC_2BTR_MODE_SELECTED (I2C_FLG_2BTR|I2C_FLG_MASTER_RECEIVER)
|
#if STM32_I2C_USE_I2C2 && !STM32_HAS_I2C2
|
||||||
#define I2C_EV6_3_MASTER_REC_1BTR_MODE_SELECTED (I2C_FLG_1BTR|I2C_FLG_MASTER_RECEIVER)
|
#error "I2C2 not present in the selected device"
|
||||||
#define I2C_EV7_2_MASTER_REC_3BYTES_TO_PROCESS (I2C_FLG_3BTR|I2C_FLG_MASTER_RECEIVER)
|
#endif
|
||||||
#define I2C_EV7_3_MASTER_REC_2BYTES_TO_PROCESS (I2C_FLG_2BTR|I2C_FLG_MASTER_RECEIVER)
|
|
||||||
|
#if STM32_I2C_USE_I2C3 && !STM32_HAS_I2C3
|
||||||
|
#error "I2C3 not present in the selected device"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !STM32_I2C_USE_I2C1 && !STM32_I2C_USE_I2C2 && \
|
||||||
|
!STM32_I2C_USE_I2C3
|
||||||
|
#error "I2C driver activated but no I2C peripheral assigned"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STM32_I2C_USE_I2C1 && \
|
||||||
|
!STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_RX_DMA_STREAM, \
|
||||||
|
STM32_I2C1_RX_DMA_MSK)
|
||||||
|
#error "invalid DMA stream associated to I2C1 RX"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STM32_I2C_USE_I2C1 && \
|
||||||
|
!STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_TX_DMA_STREAM, \
|
||||||
|
STM32_I2C1_TX_DMA_MSK)
|
||||||
|
#error "invalid DMA stream associated to I2C1 TX"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STM32_I2C_USE_I2C2 && \
|
||||||
|
!STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_RX_DMA_STREAM, \
|
||||||
|
STM32_I2C2_RX_DMA_MSK)
|
||||||
|
#error "invalid DMA stream associated to I2C2 RX"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STM32_I2C_USE_I2C2 && \
|
||||||
|
!STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_TX_DMA_STREAM, \
|
||||||
|
STM32_I2C2_TX_DMA_MSK)
|
||||||
|
#error "invalid DMA stream associated to I2C2 TX"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STM32_I2C_USE_I2C3 && \
|
||||||
|
!STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_RX_DMA_STREAM, \
|
||||||
|
STM32_I2C3_RX_DMA_MSK)
|
||||||
|
#error "invalid DMA stream associated to I2C3 RX"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STM32_I2C_USE_I2C3 && \
|
||||||
|
!STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_TX_DMA_STREAM, \
|
||||||
|
STM32_I2C3_TX_DMA_MSK)
|
||||||
|
#error "invalid DMA stream associated to I2C3 TX"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(STM32_DMA_REQUIRED)
|
||||||
|
#define STM32_DMA_REQUIRED
|
||||||
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver data structures and types. */
|
/* Driver data structures and types. */
|
||||||
|
@ -168,9 +265,6 @@ typedef struct {
|
||||||
i2copmode_t op_mode; /**< @brief Specifies the I2C mode.*/
|
i2copmode_t op_mode; /**< @brief Specifies the I2C mode.*/
|
||||||
uint32_t clock_speed; /**< @brief Specifies the clock frequency. Must be set to a value lower than 400kHz */
|
uint32_t clock_speed; /**< @brief Specifies the clock frequency. Must be set to a value lower than 400kHz */
|
||||||
i2cdutycycle_t duty_cycle; /**< @brief Specifies the I2C fast mode duty cycle */
|
i2cdutycycle_t duty_cycle; /**< @brief Specifies the I2C fast mode duty cycle */
|
||||||
uint8_t own_addr_7; /**< @brief Specifies the first device 7-bit own address. */
|
|
||||||
uint16_t own_addr_10; /**< @brief Specifies the second part of device own address in 10-bit mode. Set to NULL if not used. */
|
|
||||||
uint8_t nbit_own_addr; /**< @brief Specifies if 7-bit or 10-bit address is acknowledged */
|
|
||||||
} I2CConfig;
|
} I2CConfig;
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,11 +273,6 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
typedef struct I2CDriver I2CDriver;
|
typedef struct I2CDriver I2CDriver;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Type of a structure representing an I2C slave config.
|
|
||||||
*/
|
|
||||||
typedef struct I2CSlaveConfig I2CSlaveConfig;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Structure representing an I2C driver.
|
* @brief Structure representing an I2C driver.
|
||||||
*/
|
*/
|
||||||
|
@ -191,72 +280,46 @@ struct I2CDriver{
|
||||||
/**
|
/**
|
||||||
* @brief Driver state.
|
* @brief Driver state.
|
||||||
*/
|
*/
|
||||||
i2cstate_t id_state;
|
i2cstate_t id_state;
|
||||||
|
|
||||||
#if I2C_USE_WAIT
|
|
||||||
/**
|
/**
|
||||||
* @brief Thread waiting for I/O completion.
|
* @brief Thread waiting for I/O completion.
|
||||||
*/
|
*/
|
||||||
Thread *id_thread;
|
Thread *id_thread;
|
||||||
#endif /* I2C_USE_WAIT */
|
|
||||||
#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
|
#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
|
||||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief Mutex protecting the bus.
|
* @brief Mutex protecting the bus.
|
||||||
*/
|
*/
|
||||||
Mutex id_mutex;
|
Mutex id_mutex;
|
||||||
#elif CH_USE_SEMAPHORES
|
#elif CH_USE_SEMAPHORES
|
||||||
Semaphore id_semaphore;
|
Semaphore id_semaphore;
|
||||||
#endif
|
#endif
|
||||||
#endif /* I2C_USE_MUTUAL_EXCLUSION */
|
#endif /* I2C_USE_MUTUAL_EXCLUSION */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Current configuration data.
|
* @brief Current configuration data.
|
||||||
*/
|
*/
|
||||||
const I2CConfig *id_config;
|
const I2CConfig *id_config;
|
||||||
/**
|
|
||||||
* @brief Current slave configuration data.
|
|
||||||
*/
|
|
||||||
const I2CSlaveConfig *id_slave_config;
|
|
||||||
|
|
||||||
__IO size_t txbytes; /*!< @brief Number of bytes to be transmitted. */
|
__IO size_t txbytes; /*!< @brief Number of bytes to be transmitted. */
|
||||||
__IO size_t rxbytes; /*!< @brief Number of bytes to be received. */
|
__IO size_t rxbytes; /*!< @brief Number of bytes to be received. */
|
||||||
uint8_t *rxbuf; /*!< @brief Pointer to receive buffer. */
|
uint8_t *rxbuf; /*!< @brief Pointer to receive buffer. */
|
||||||
uint8_t *txbuf; /*!< @brief Pointer to transmit buffer.*/
|
uint8_t *txbuf; /*!< @brief Pointer to transmit buffer.*/
|
||||||
uint8_t *rxbuff_p; /*!< @brief Pointer to the current byte in slave rx buffer. */
|
|
||||||
uint8_t *txbuff_p; /*!< @brief Pointer to the current byte in slave tx buffer. */
|
|
||||||
|
|
||||||
__IO i2cflags_t errors; /*!< @brief Error flags.*/
|
__IO i2cflags_t errors; /*!< @brief Error flags.*/
|
||||||
__IO i2cflags_t flags; /*!< @brief State flags.*/
|
__IO i2cflags_t flags; /*!< @brief State flags.*/
|
||||||
|
|
||||||
uint16_t slave_addr; /*!< @brief Current slave address. */
|
uint8_t slave_addr; /*!< @brief Current slave address without R/W bit. */
|
||||||
uint8_t slave_addr1;/*!< @brief 7-bit address of the slave with r\w bit.*/
|
|
||||||
uint8_t slave_addr2;/*!< @brief Uses in 10-bit address mode. */
|
|
||||||
|
|
||||||
#if CH_USE_EVENTS
|
|
||||||
EventSource sevent; /*!< @brief Status Change @p EventSource.*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********** End of the mandatory fields. **********************************/
|
/*********** End of the mandatory fields. **********************************/
|
||||||
|
|
||||||
/**
|
uint32_t dmamode; /*!< @brief DMA mode bit mask.*/
|
||||||
* @brief Pointer to the I2Cx registers block.
|
const stm32_dma_stream_t *dmarx; /*!< @brief Receive DMA channel.*/
|
||||||
*/
|
const stm32_dma_stream_t *dmatx; /*!< @brief Transmit DMA channel.*/
|
||||||
I2C_TypeDef *id_i2c;
|
|
||||||
|
|
||||||
#if !(STM32_I2C_I2C1_USE_POLLING_WAIT)
|
I2C_TypeDef *id_i2c; /*!< @brief Pointer to the I2Cx registers block. */
|
||||||
/* TODO: capability to switch this GPT fields off */
|
|
||||||
/**
|
|
||||||
* @brief Timer for waiting STOP condition on the bus.
|
|
||||||
* @details This is workaround for STM32 buggy I2C cell.
|
|
||||||
*/
|
|
||||||
GPTDriver *timer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Config for workaround timer.
|
|
||||||
*/
|
|
||||||
const GPTConfig *timer_cfg;
|
|
||||||
#endif /* !(STM32_I2C_I2C1_USE_POLLING_WAIT) */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -268,8 +331,7 @@ struct I2CDriver{
|
||||||
(i2cp->id_i2c->SR2 & I2C_SR2_BUSY)
|
(i2cp->id_i2c->SR2 & I2C_SR2_BUSY)
|
||||||
|
|
||||||
|
|
||||||
/* Wait until BUSY flag is reset: a STOP has been generated on the bus
|
/* Wait until BUSY flag is reset. Normally this wait function
|
||||||
* signaling the end of transmission. Normally this wait function
|
|
||||||
* does not block thread, only if slave not response it does.
|
* does not block thread, only if slave not response it does.
|
||||||
*/
|
*/
|
||||||
#define i2c_lld_wait_bus_free(i2cp) { \
|
#define i2c_lld_wait_bus_free(i2cp) { \
|
||||||
|
@ -291,6 +353,10 @@ extern I2CDriver I2CD1;
|
||||||
extern I2CDriver I2CD2;
|
extern I2CDriver I2CD2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if STM32_I2C_USE_I2C3
|
||||||
|
extern I2CDriver I2CD3;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -299,14 +365,12 @@ void i2c_lld_init(void);
|
||||||
void i2c_lld_reset(I2CDriver *i2cp);
|
void i2c_lld_reset(I2CDriver *i2cp);
|
||||||
void i2c_lld_set_clock(I2CDriver *i2cp);
|
void i2c_lld_set_clock(I2CDriver *i2cp);
|
||||||
void i2c_lld_set_opmode(I2CDriver *i2cp);
|
void i2c_lld_set_opmode(I2CDriver *i2cp);
|
||||||
void i2c_lld_set_own_address(I2CDriver *i2cp);
|
|
||||||
void i2c_lld_start(I2CDriver *i2cp);
|
void i2c_lld_start(I2CDriver *i2cp);
|
||||||
void i2c_lld_stop(I2CDriver *i2cp);
|
void i2c_lld_stop(I2CDriver *i2cp);
|
||||||
void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr,
|
void i2c_lld_master_transmit(I2CDriver *i2cp, uint8_t slave_addr,
|
||||||
uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes);
|
uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes);
|
||||||
void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr,
|
void i2c_lld_master_receive(I2CDriver *i2cp, uint8_t slave_addr,
|
||||||
uint8_t *rxbuf, size_t rxbytes);
|
uint8_t *rxbuf, size_t rxbytes);
|
||||||
void i2c_lld_master_transceive(I2CDriver *i2cp);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,8 +295,22 @@
|
||||||
|
|
||||||
/* I2C attributes.*/
|
/* I2C attributes.*/
|
||||||
#define STM32_HAS_I2C1 TRUE
|
#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_I2C2 TRUE
|
#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_I2C3 FALSE
|
#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.*/
|
/* RTC attributes.*/
|
||||||
#define STM32_HAS_RTC TRUE
|
#define STM32_HAS_RTC TRUE
|
||||||
|
|
|
@ -306,8 +306,24 @@
|
||||||
|
|
||||||
/* I2C attributes.*/
|
/* I2C attributes.*/
|
||||||
#define STM32_HAS_I2C1 TRUE
|
#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_I2C2 TRUE
|
#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_I2C3 FALSE
|
#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.*/
|
/* RTC attributes.*/
|
||||||
#define STM32_HAS_RTC TRUE
|
#define STM32_HAS_RTC TRUE
|
||||||
|
|
|
@ -166,8 +166,22 @@
|
||||||
|
|
||||||
/* I2C attributes.*/
|
/* I2C attributes.*/
|
||||||
#define STM32_HAS_I2C1 TRUE
|
#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_I2C2 TRUE
|
#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_I2C3 FALSE
|
#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.*/
|
/* RTC attributes.*/
|
||||||
#define STM32_HAS_RTC TRUE
|
#define STM32_HAS_RTC TRUE
|
||||||
|
|
|
@ -157,8 +157,27 @@
|
||||||
#define STM32_HAS_GPIOH TRUE
|
#define STM32_HAS_GPIOH TRUE
|
||||||
#define STM32_HAS_GPIOI TRUE
|
#define STM32_HAS_GPIOI TRUE
|
||||||
|
|
||||||
|
/* I2C attributes.*/
|
||||||
#define STM32_HAS_I2C1 TRUE
|
#define STM32_HAS_I2C1 TRUE
|
||||||
|
#define STM32_I2C1_RX_DMA_MSK ((STM32_DMA_STREAM_ID_MSK(1, 0) | \
|
||||||
|
STM32_DMA_STREAM_ID_MSK(1, 5)))
|
||||||
|
#define STM32_I2C1_RX_DMA_CHN 0x00100001
|
||||||
|
#define STM32_I2C1_TX_DMA_MSK ((STM32_DMA_STREAM_ID_MSK(1, 7)) | \
|
||||||
|
(STM32_DMA_STREAM_ID_MSK(1, 6)))
|
||||||
|
#define STM32_I2C1_TX_DMA_CHN 0x10000000
|
||||||
|
|
||||||
#define STM32_HAS_I2C2 TRUE
|
#define STM32_HAS_I2C2 TRUE
|
||||||
|
#define STM32_I2C2_RX_DMA_MSK ((STM32_DMA_STREAM_ID_MSK(1, 2) | \
|
||||||
|
STM32_DMA_STREAM_ID_MSK(1, 3)))
|
||||||
|
#define STM32_I2C2_RX_DMA_CHN 0x00007700
|
||||||
|
#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
|
||||||
|
#define STM32_I2C2_TX_DMA_CHN 0x70000000
|
||||||
|
|
||||||
|
#define STM32_HAS_I2C3 TRUE
|
||||||
|
#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
|
||||||
|
#define STM32_I2C3_RX_DMA_CHN 0x00000300
|
||||||
|
#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
|
||||||
|
#define STM32_I2C3_TX_DMA_CHN 0x00030000
|
||||||
|
|
||||||
#define STM32_HAS_RTC TRUE
|
#define STM32_HAS_RTC TRUE
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F4xx/stm32_dma.c \
|
||||||
${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \
|
${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \
|
||||||
${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \
|
${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \
|
||||||
${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \
|
${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \
|
||||||
|
${CHIBIOS}/os/hal/platforms/STM32/i2c_lld.c \
|
||||||
${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c
|
${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c
|
||||||
|
|
||||||
# Required include directories
|
# Required include directories
|
||||||
|
|
|
@ -198,8 +198,22 @@
|
||||||
|
|
||||||
/* I2C attributes.*/
|
/* I2C attributes.*/
|
||||||
#define STM32_HAS_I2C1 TRUE
|
#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_I2C2 TRUE
|
#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_I2C3 FALSE
|
#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.*/
|
/* RTC attributes.*/
|
||||||
#define STM32_HAS_RTC TRUE
|
#define STM32_HAS_RTC TRUE
|
||||||
|
|
|
@ -73,15 +73,9 @@ void i2cObjectInit(I2CDriver *i2cp) {
|
||||||
|
|
||||||
i2cp->id_state = I2C_STOP;
|
i2cp->id_state = I2C_STOP;
|
||||||
i2cp->id_config = NULL;
|
i2cp->id_config = NULL;
|
||||||
i2cp->rxbuff_p = NULL;
|
|
||||||
i2cp->txbuff_p = NULL;
|
|
||||||
i2cp->rxbuf = NULL;
|
i2cp->rxbuf = NULL;
|
||||||
i2cp->txbuf = NULL;
|
i2cp->txbuf = NULL;
|
||||||
i2cp->id_slave_config = NULL;
|
|
||||||
|
|
||||||
#if I2C_USE_WAIT
|
|
||||||
i2cp->id_thread = NULL;
|
i2cp->id_thread = NULL;
|
||||||
#endif /* I2C_USE_WAIT */
|
|
||||||
|
|
||||||
#if I2C_USE_MUTUAL_EXCLUSION
|
#if I2C_USE_MUTUAL_EXCLUSION
|
||||||
#if CH_USE_MUTEXES
|
#if CH_USE_MUTEXES
|
||||||
|
@ -111,10 +105,6 @@ void i2cStart(I2CDriver *i2cp, const I2CConfig *config) {
|
||||||
"i2cStart(), #1",
|
"i2cStart(), #1",
|
||||||
"invalid state");
|
"invalid state");
|
||||||
|
|
||||||
#if (!(STM32_I2C_I2C2_USE_POLLING_WAIT) && I2C_SUPPORTS_CALLBACKS)
|
|
||||||
gptStart(i2cp->timer, i2cp->timer_cfg);
|
|
||||||
#endif /* !(STM32_I2C_I2C2_USE_POLLING_WAIT) */
|
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
i2cp->id_config = config;
|
i2cp->id_config = config;
|
||||||
i2c_lld_start(i2cp);
|
i2c_lld_start(i2cp);
|
||||||
|
@ -136,10 +126,6 @@ void i2cStop(I2CDriver *i2cp) {
|
||||||
"i2cStop(), #1",
|
"i2cStop(), #1",
|
||||||
"invalid state");
|
"invalid state");
|
||||||
|
|
||||||
#if (!(STM32_I2C_I2C2_USE_POLLING_WAIT) && I2C_SUPPORTS_CALLBACKS)
|
|
||||||
gptStop(i2cp->timer);
|
|
||||||
#endif /* !(STM32_I2C_I2C2_USE_POLLING_WAIT) */
|
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
i2c_lld_stop(i2cp);
|
i2c_lld_stop(i2cp);
|
||||||
i2cp->id_state = I2C_STOP;
|
i2cp->id_state = I2C_STOP;
|
||||||
|
@ -153,35 +139,33 @@ void i2cStop(I2CDriver *i2cp) {
|
||||||
* paradigm. If you want transmit data without any further read,
|
* paradigm. If you want transmit data without any further read,
|
||||||
* than set @b rxbytes field to 0.
|
* than set @b rxbytes field to 0.
|
||||||
*
|
*
|
||||||
|
* @details Number of receiving byts must be 0 or more than 1 because of stm32
|
||||||
|
* hardware restrictions.
|
||||||
|
*
|
||||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||||
* @param[in] i2cscfg pointer to the @p I2C slave config
|
* @param[in] slave_addr Slave device address (7 bits) without R/W bit
|
||||||
* @param[in] slave_addr Slave device address. Bits 0-9 contain slave
|
|
||||||
* device address. Bit 15 must be set to 1 if 10-bit
|
|
||||||
* addressing mode used. Otherwise keep it cleared.
|
|
||||||
* Bits 10-14 unused.
|
|
||||||
* @param[in] txbuf pointer to transmit buffer
|
* @param[in] txbuf pointer to transmit buffer
|
||||||
* @param[in] txbytes number of bytes to be transmitted
|
* @param[in] txbytes number of bytes to be transmitted
|
||||||
* @param[in] rxbuf pointer to receive buffer
|
* @param[in] rxbuf pointer to receive buffer
|
||||||
* @param[in] rxbytes number of bytes to be received, set it to 0 if
|
* @param[in] rxbytes number of bytes to be received, set it to 0 if
|
||||||
* you want transmit only
|
* you want transmit only
|
||||||
|
*
|
||||||
|
* @return Zero if no errors, otherwise return error code.
|
||||||
*/
|
*/
|
||||||
void i2cMasterTransmit(I2CDriver *i2cp,
|
i2cflags_t i2cMasterTransmit(I2CDriver *i2cp,
|
||||||
const I2CSlaveConfig *i2cscfg,
|
uint8_t slave_addr,
|
||||||
uint16_t slave_addr,
|
|
||||||
uint8_t *txbuf,
|
uint8_t *txbuf,
|
||||||
size_t txbytes,
|
size_t txbytes,
|
||||||
uint8_t *rxbuf,
|
uint8_t *rxbuf,
|
||||||
size_t rxbytes) {
|
size_t rxbytes) {
|
||||||
|
|
||||||
chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) &&\
|
chDbgCheck((i2cp != NULL) &&\
|
||||||
(slave_addr != 0) &&\
|
(slave_addr != 0) &&\
|
||||||
(txbytes > 0) &&\
|
(txbytes > 0) &&\
|
||||||
(txbuf != NULL),
|
(txbuf != NULL) &&\
|
||||||
|
((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))),
|
||||||
"i2cMasterTransmit");
|
"i2cMasterTransmit");
|
||||||
|
|
||||||
/* init slave config field in driver */
|
|
||||||
i2cp->id_slave_config = i2cscfg;
|
|
||||||
|
|
||||||
i2c_lld_wait_bus_free(i2cp);
|
i2c_lld_wait_bus_free(i2cp);
|
||||||
chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), "i2cMasterReceive(), #1", "time is out");
|
chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), "i2cMasterReceive(), #1", "time is out");
|
||||||
|
|
||||||
|
@ -190,40 +174,34 @@ void i2cMasterTransmit(I2CDriver *i2cp,
|
||||||
|
|
||||||
i2cp->id_state = I2C_ACTIVE_TRANSMIT;
|
i2cp->id_state = I2C_ACTIVE_TRANSMIT;
|
||||||
i2c_lld_master_transmit(i2cp, slave_addr, txbuf, txbytes, rxbuf, rxbytes);
|
i2c_lld_master_transmit(i2cp, slave_addr, txbuf, txbytes, rxbuf, rxbytes);
|
||||||
#if I2C_SUPPORTS_CALLBACKS
|
|
||||||
_i2c_wait_s(i2cp);
|
_i2c_wait_s(i2cp);
|
||||||
#else
|
|
||||||
i2cp->id_state = I2C_READY;
|
return i2cGetAndClearFlags(i2cp);
|
||||||
#endif /* I2C_SUPPORTS_CALLBACKS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Receives data from the I2C bus.
|
* @brief Receives data from the I2C bus.
|
||||||
|
* @details Number of receiving byts must be more than 1 because of stm32
|
||||||
|
* hardware restrictions.
|
||||||
*
|
*
|
||||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||||
* @param[in] i2cscfg pointer to the @p I2C slave config
|
* @param[in] slave_addr slave device address (7 bits) without R/W bit
|
||||||
* @param[in] slave_addr Slave device address. Bits 0-9 contain slave
|
|
||||||
* device address. Bit 15 must be set to 1 if 10-bit
|
|
||||||
* addressing mode used. Otherwise keep it cleared.
|
|
||||||
* Bits 10-14 unused.
|
|
||||||
* @param[in] rxbytes number of bytes to be received
|
* @param[in] rxbytes number of bytes to be received
|
||||||
* @param[in] rxbuf pointer to receive buffer
|
* @param[in] rxbuf pointer to receive buffer
|
||||||
|
*
|
||||||
|
* @return Zero if no errors, otherwise return error code.
|
||||||
*/
|
*/
|
||||||
void i2cMasterReceive(I2CDriver *i2cp,
|
i2cflags_t i2cMasterReceive(I2CDriver *i2cp,
|
||||||
const I2CSlaveConfig *i2cscfg,
|
uint8_t slave_addr,
|
||||||
uint16_t slave_addr,
|
|
||||||
uint8_t *rxbuf,
|
uint8_t *rxbuf,
|
||||||
size_t rxbytes){
|
size_t rxbytes){
|
||||||
|
|
||||||
chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) &&\
|
chDbgCheck((i2cp != NULL) &&\
|
||||||
(slave_addr != 0) &&\
|
(slave_addr != 0) &&\
|
||||||
(rxbytes > 0) && \
|
(rxbytes > 1) && \
|
||||||
(rxbuf != NULL),
|
(rxbuf != NULL),
|
||||||
"i2cMasterReceive");
|
"i2cMasterReceive");
|
||||||
|
|
||||||
/* init slave config field in driver */
|
|
||||||
i2cp->id_slave_config = i2cscfg;
|
|
||||||
|
|
||||||
i2c_lld_wait_bus_free(i2cp);
|
i2c_lld_wait_bus_free(i2cp);
|
||||||
chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), "i2cMasterReceive(), #1", "time is out");
|
chDbgAssert(!(i2c_lld_bus_is_busy(i2cp)), "i2cMasterReceive(), #1", "time is out");
|
||||||
|
|
||||||
|
@ -232,20 +210,10 @@ void i2cMasterReceive(I2CDriver *i2cp,
|
||||||
|
|
||||||
i2cp->id_state = I2C_ACTIVE_RECEIVE;
|
i2cp->id_state = I2C_ACTIVE_RECEIVE;
|
||||||
i2c_lld_master_receive(i2cp, slave_addr, rxbuf, rxbytes);
|
i2c_lld_master_receive(i2cp, slave_addr, rxbuf, rxbytes);
|
||||||
#if I2C_SUPPORTS_CALLBACKS
|
|
||||||
_i2c_wait_s(i2cp);
|
_i2c_wait_s(i2cp);
|
||||||
#else
|
|
||||||
i2cp->id_state = I2C_READY;
|
|
||||||
#endif /* I2C_SUPPORTS_CALLBACKS */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return i2cGetAndClearFlags(i2cp);
|
||||||
/* FIXME: I do not know what this function must do. And can not test it
|
|
||||||
uint16_t i2cSMBusAlertResponse(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg) {
|
|
||||||
i2cMasterReceive(i2cp, i2cscfg);
|
|
||||||
return i2cp->id_slave_config->slave_addr;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handles communication events/errors.
|
* @brief Handles communication events/errors.
|
||||||
|
@ -262,7 +230,6 @@ void i2cAddFlagsI(I2CDriver *i2cp, i2cflags_t mask) {
|
||||||
chDbgCheck(i2cp != NULL, "i2cAddFlagsI");
|
chDbgCheck(i2cp != NULL, "i2cAddFlagsI");
|
||||||
|
|
||||||
i2cp->errors |= mask;
|
i2cp->errors |= mask;
|
||||||
chEvtBroadcastI(&i2cp->sevent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -323,7 +290,6 @@ void i2cReleaseBus(I2CDriver *i2cp) {
|
||||||
chDbgCheck(i2cp != NULL, "i2cReleaseBus");
|
chDbgCheck(i2cp != NULL, "i2cReleaseBus");
|
||||||
|
|
||||||
#if CH_USE_MUTEXES
|
#if CH_USE_MUTEXES
|
||||||
(void)i2cp;
|
|
||||||
chMtxUnlock();
|
chMtxUnlock();
|
||||||
#elif CH_USE_SEMAPHORES
|
#elif CH_USE_SEMAPHORES
|
||||||
chSemSignal(&i2cp->id_semaphore);
|
chSemSignal(&i2cp->id_semaphore);
|
||||||
|
|
|
@ -31,7 +31,7 @@ endif
|
||||||
|
|
||||||
# Enable this if you want to see the full log while compiling.
|
# Enable this if you want to see the full log while compiling.
|
||||||
ifeq ($(USE_VERBOSE_COMPILE),)
|
ifeq ($(USE_VERBOSE_COMPILE),)
|
||||||
USE_VERBOSE_COMPILE = no
|
USE_VERBOSE_COMPILE = yes
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -63,7 +63,7 @@ LDSCRIPT= $(PORTLD)/STM32F103xB.ld
|
||||||
|
|
||||||
# Imported source files
|
# Imported source files
|
||||||
CHIBIOS = ../../..
|
CHIBIOS = ../../..
|
||||||
include $(CHIBIOS)/boards/OLIMEX_STM32_P103/board.mk
|
include $(CHIBIOS)/boards/OLIMEX_STM32_103STK/board.mk
|
||||||
include $(CHIBIOS)/os/hal/platforms/STM32F1xx/platform.mk
|
include $(CHIBIOS)/os/hal/platforms/STM32F1xx/platform.mk
|
||||||
include $(CHIBIOS)/os/hal/hal.mk
|
include $(CHIBIOS)/os/hal/hal.mk
|
||||||
include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F1xx/port.mk
|
include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F1xx/port.mk
|
||||||
|
@ -82,9 +82,9 @@ CSRC = $(PORTSRC) \
|
||||||
$(CHIBIOS)/os/various/syscalls.c \
|
$(CHIBIOS)/os/various/syscalls.c \
|
||||||
main.c \
|
main.c \
|
||||||
i2c_pns.c \
|
i2c_pns.c \
|
||||||
tmp75.c\
|
lis3.c \
|
||||||
max1236.c\
|
tmp75.c \
|
||||||
lis3.c\
|
fake.c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,7 +127,6 @@ INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
|
||||||
# Compiler settings
|
# Compiler settings
|
||||||
#
|
#
|
||||||
|
|
||||||
# -lm <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
MCU = cortex-m3
|
MCU = cortex-m3
|
||||||
|
|
||||||
#TRGT = arm-elf-
|
#TRGT = arm-elf-
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||||
|
2011 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not responding slave test
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "ch.h"
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
#include "fake.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* input buffer */
|
||||||
|
static uint8_t rx_data[2];
|
||||||
|
|
||||||
|
/* temperature value */
|
||||||
|
static int16_t temperature = 0;
|
||||||
|
|
||||||
|
|
||||||
|
#define addr 0b1001100
|
||||||
|
|
||||||
|
/* This is main function. */
|
||||||
|
void request_fake(void){
|
||||||
|
i2cflags_t errors = 0;
|
||||||
|
|
||||||
|
i2cAcquireBus(&I2CD1);
|
||||||
|
errors = i2cMasterReceive(&I2CD1, addr, rx_data, 2);
|
||||||
|
i2cReleaseBus(&I2CD1);
|
||||||
|
|
||||||
|
if (errors == I2CD_ACK_FAILURE){
|
||||||
|
__NOP();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
temperature = (rx_data[0] << 8) + rx_data[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||||
|
2011 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FAKE_H_
|
||||||
|
#define FAKE_H_
|
||||||
|
|
||||||
|
void request_fake(void);
|
||||||
|
|
||||||
|
#endif /* FAKE_H_ */
|
|
@ -44,7 +44,7 @@
|
||||||
* @brief Enables the ADC subsystem.
|
* @brief Enables the ADC subsystem.
|
||||||
*/
|
*/
|
||||||
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
|
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
|
||||||
#define HAL_USE_ADC TRUE
|
#define HAL_USE_ADC FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
* @brief Enables the PWM subsystem.
|
* @brief Enables the PWM subsystem.
|
||||||
*/
|
*/
|
||||||
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
|
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
|
||||||
#define HAL_USE_PWM TRUE
|
#define HAL_USE_PWM FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,7 +121,7 @@
|
||||||
* @brief Enables the SERIAL subsystem.
|
* @brief Enables the SERIAL subsystem.
|
||||||
*/
|
*/
|
||||||
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
|
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
|
||||||
#define HAL_USE_SERIAL TRUE
|
#define HAL_USE_SERIAL FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -192,7 +192,7 @@
|
||||||
* @note Disabling this option saves both code and data space.
|
* @note Disabling this option saves both code and data space.
|
||||||
*/
|
*/
|
||||||
#if !defined(I2C_USE_WAIT) || defined(__DOXYGEN__)
|
#if !defined(I2C_USE_WAIT) || defined(__DOXYGEN__)
|
||||||
#define I2C_USE_WAIT FALSE
|
#define I2C_USE_WAIT TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -202,13 +202,6 @@
|
||||||
#define I2C_USE_MUTUAL_EXCLUSION TRUE
|
#define I2C_USE_MUTUAL_EXCLUSION TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Switch to asynchronouse driver with callbacks.
|
|
||||||
*/
|
|
||||||
#if !defined(I2C_SUPPORTS_CALLBACKS) || defined(__DOXYGEN__)
|
|
||||||
#define I2C_SUPPORTS_CALLBACKS TRUE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* MAC driver related settings. */
|
/* MAC driver related settings. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
|
@ -1,32 +1,35 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||||
|
2011 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
#include "i2c_pns.h"
|
#include "i2c_pns.h"
|
||||||
|
|
||||||
#include "lis3.h"
|
#include "lis3.h"
|
||||||
#include "tmp75.h"
|
|
||||||
#include "max1236.h"
|
|
||||||
|
|
||||||
/* I2C1 */
|
/* I2C1 */
|
||||||
static const I2CConfig i2cfg1 = {
|
static const I2CConfig i2cfg1 = {
|
||||||
OPMODE_I2C,
|
OPMODE_I2C,
|
||||||
100000,
|
400000,
|
||||||
STD_DUTY_CYCLE,
|
FAST_DUTY_CYCLE_16_9,
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* I2C2 */
|
|
||||||
static const I2CConfig i2cfg2 = {
|
|
||||||
OPMODE_I2C,
|
|
||||||
100000,
|
|
||||||
STD_DUTY_CYCLE,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,22 +38,14 @@ void I2CInit_pns(void){
|
||||||
i2cInit();
|
i2cInit();
|
||||||
|
|
||||||
i2cStart(&I2CD1, &i2cfg1);
|
i2cStart(&I2CD1, &i2cfg1);
|
||||||
i2cStart(&I2CD2, &i2cfg2);
|
|
||||||
|
|
||||||
/* tune ports for I2C1*/
|
/* tune ports for I2C1*/
|
||||||
palSetPadMode(IOPORT2, 6, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
|
palSetPadMode(IOPORT2, 6, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
|
||||||
palSetPadMode(IOPORT2, 7, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
|
palSetPadMode(IOPORT2, 7, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
|
||||||
|
|
||||||
/* tune ports for I2C2*/
|
|
||||||
palSetPadMode(IOPORT2, 10, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
|
|
||||||
palSetPadMode(IOPORT2, 11, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
|
|
||||||
|
|
||||||
/* startups. Pauses added just to be safe */
|
/* startups. Pauses added just to be safe */
|
||||||
chThdSleepMilliseconds(1000);
|
chThdSleepMilliseconds(100);
|
||||||
init_max1236();
|
|
||||||
chThdSleepMilliseconds(1000);
|
|
||||||
init_lis3();
|
init_lis3();
|
||||||
chThdSleepMilliseconds(1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||||
|
2011 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef I2C_PNS_H_
|
#ifndef I2C_PNS_H_
|
||||||
#define I2C_PNS_H_
|
#define I2C_PNS_H_
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,26 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||||
|
2011 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is most complex and difficult device.
|
* This is device realize "read through write" paradigm. This is not
|
||||||
* It realize "read through write" paradigm. This is not standard, but
|
* standard, but most of I2C devices use this paradigm.
|
||||||
* most of I2C devices use this paradigm.
|
|
||||||
* You must write to device reading address, send restart to bus,
|
* You must write to device reading address, send restart to bus,
|
||||||
* and then begin reading process.
|
* and then begin reading process.
|
||||||
*/
|
*/
|
||||||
|
@ -18,34 +37,13 @@
|
||||||
|
|
||||||
|
|
||||||
/* buffers */
|
/* buffers */
|
||||||
static i2cblock_t accel_rx_data[ACCEL_RX_DEPTH];
|
static uint8_t accel_rx_data[ACCEL_RX_DEPTH];
|
||||||
static i2cblock_t accel_tx_data[ACCEL_TX_DEPTH];
|
static uint8_t accel_tx_data[ACCEL_TX_DEPTH];
|
||||||
|
|
||||||
static int16_t acceleration_x = 0;
|
static int16_t acceleration_x = 0;
|
||||||
static int16_t acceleration_y = 0;
|
static int16_t acceleration_y = 0;
|
||||||
static int16_t acceleration_z = 0;
|
static int16_t acceleration_z = 0;
|
||||||
|
|
||||||
/* Error trap */
|
|
||||||
static void i2c_lis3_error_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){
|
|
||||||
(void)i2cscfg;
|
|
||||||
int status = 0;
|
|
||||||
status = i2cp->id_i2c->SR1;
|
|
||||||
while(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This callback raise up when transfer finished */
|
|
||||||
static void i2c_lis3_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){
|
|
||||||
(void)i2cp;
|
|
||||||
(void)i2cscfg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Accelerometer lis3lv02dq config */
|
|
||||||
static const I2CSlaveConfig lis3 = {
|
|
||||||
i2c_lis3_cb,
|
|
||||||
i2c_lis3_error_cb,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init function. Here we will also start personal serving thread.
|
* Init function. Here we will also start personal serving thread.
|
||||||
|
@ -58,7 +56,9 @@ int init_lis3(void){
|
||||||
accel_tx_data[3] = 0b00000000;
|
accel_tx_data[3] = 0b00000000;
|
||||||
|
|
||||||
/* sending */
|
/* sending */
|
||||||
i2cMasterTransmit(&I2CD1, &lis3, lis3_addr, accel_tx_data, 4, accel_rx_data, 0);
|
i2cAcquireBus(&I2CD1);
|
||||||
|
i2cMasterTransmit(&I2CD1, lis3_addr, accel_tx_data, 4, accel_rx_data, 0);
|
||||||
|
i2cReleaseBus(&I2CD1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,9 +67,9 @@ int init_lis3(void){
|
||||||
*/
|
*/
|
||||||
void request_acceleration_data(void){
|
void request_acceleration_data(void){
|
||||||
accel_tx_data[0] = ACCEL_OUT_DATA | AUTO_INCREMENT_BIT; // register address
|
accel_tx_data[0] = ACCEL_OUT_DATA | AUTO_INCREMENT_BIT; // register address
|
||||||
//i2cAcquireBus(&I2CD1);
|
i2cAcquireBus(&I2CD1);
|
||||||
i2cMasterTransmit(&I2CD1, &lis3, lis3_addr, accel_tx_data, 1, accel_rx_data, 6);
|
i2cMasterTransmit(&I2CD1, lis3_addr, accel_tx_data, 1, accel_rx_data, 6);
|
||||||
//i2cReleaseBus(&I2CD1);
|
i2cReleaseBus(&I2CD1);
|
||||||
|
|
||||||
acceleration_x = accel_rx_data[0] + (accel_rx_data[1] << 8);
|
acceleration_x = accel_rx_data[0] + (accel_rx_data[1] << 8);
|
||||||
acceleration_y = accel_rx_data[2] + (accel_rx_data[3] << 8);
|
acceleration_y = accel_rx_data[2] + (accel_rx_data[3] << 8);
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||||
|
2011 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
/**
|
/*
|
||||||
* Lets imagine that we have board with LIS3LV02DL accelerometer on channel #1
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||||
* and MAX1236 ADC, TMP75 thermometer on channel #2.
|
2011 Giovanni Di Sirio.
|
||||||
*
|
|
||||||
* NOTE: I assume, that you have datasheets on all this stuff.
|
This file is part of ChibiOS/RT.
|
||||||
*
|
|
||||||
* NOTE: Also, I assume, that you know how to I2C works.
|
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
|
||||||
* In order from simplicity to complexity:
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
* TMP75
|
(at your option) any later version.
|
||||||
* MAX1236
|
|
||||||
* LIS3LV02DL
|
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||||
*
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* Project splitted to separate source files for each device.
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
*
|
GNU General Public License for more details.
|
||||||
* Data from sensors we will be read from different thread sleeping different
|
|
||||||
* amount of time.
|
You should have received a copy of the GNU General Public License
|
||||||
*/
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -23,10 +24,9 @@
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
#include "i2c_pns.h"
|
#include "i2c_pns.h"
|
||||||
#include "tmp75.h"
|
|
||||||
#include "max1236.h"
|
|
||||||
#include "lis3.h"
|
#include "lis3.h"
|
||||||
|
#include "tmp75.h"
|
||||||
|
#include "fake.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -44,55 +44,51 @@ static msg_t Blink(void *arg) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Accelerometer thread
|
||||||
|
*/
|
||||||
|
static WORKING_AREA(PollAccelThreadWA, 128);
|
||||||
|
static msg_t PollAccelThread(void *arg) {
|
||||||
|
chRegSetThreadName("PollAccel");
|
||||||
|
(void)arg;
|
||||||
|
while (TRUE) {
|
||||||
|
// chThdSleepMilliseconds(rand() & 31);
|
||||||
|
chThdSleepMilliseconds(32);
|
||||||
|
request_acceleration_data();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Temperature polling thread */
|
/* Temperature polling thread */
|
||||||
static WORKING_AREA(PollTmp75ThreadWA, 128);
|
static WORKING_AREA(PollTmp75ThreadWA, 128);
|
||||||
static msg_t PollTmp75Thread(void *arg) {
|
static msg_t PollTmp75Thread(void *arg) {
|
||||||
|
chRegSetThreadName("PollTmp75");
|
||||||
(void)arg;
|
(void)arg;
|
||||||
systime_t time = chTimeNow();
|
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
time += MS2ST(1001);
|
// chThdSleepMilliseconds(rand() & 31);
|
||||||
|
chThdSleepMilliseconds(15);
|
||||||
/* Call reading function */
|
/* Call reading function */
|
||||||
request_temperature();
|
request_temperature();
|
||||||
chThdSleepUntil(time);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MAX1236 polling thread */
|
|
||||||
static WORKING_AREA(PollMax1236ThreadWA, 128);
|
|
||||||
static msg_t PollMax1236Thread(void *arg) {
|
|
||||||
(void)arg;
|
|
||||||
systime_t time = chTimeNow();
|
|
||||||
|
|
||||||
|
/* Temperature polling thread */
|
||||||
|
static WORKING_AREA(PollFakeThreadWA, 128);
|
||||||
|
static msg_t PollFakeThread(void *arg) {
|
||||||
|
chRegSetThreadName("PollFake");
|
||||||
|
(void)arg;
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
time += MS2ST(200);
|
chThdSleepMilliseconds(16);
|
||||||
/* Call reading function */
|
/* Call reading function */
|
||||||
read_max1236();
|
request_fake();
|
||||||
chThdSleepUntil(time);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static WORKING_AREA(PollAccelThreadWA, 128);
|
|
||||||
static msg_t PollAccelThread(void *arg) {
|
|
||||||
(void)arg;
|
|
||||||
systime_t time = chTimeNow();
|
|
||||||
|
|
||||||
while (TRUE) {
|
|
||||||
time += MS2ST(20);
|
|
||||||
request_acceleration_data();
|
|
||||||
chThdSleepUntil(time);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Entry point, note, the main() function is already a thread in the system
|
* Entry point, note, the main() function is already a thread in the system
|
||||||
* on entry.
|
* on entry.
|
||||||
|
@ -102,8 +98,16 @@ int main(void) {
|
||||||
halInit();
|
halInit();
|
||||||
chSysInit();
|
chSysInit();
|
||||||
|
|
||||||
|
chThdSleepMilliseconds(200);
|
||||||
I2CInit_pns();
|
I2CInit_pns();
|
||||||
|
|
||||||
|
/* Create accelerometer thread */
|
||||||
|
chThdCreateStatic(PollAccelThreadWA,
|
||||||
|
sizeof(PollAccelThreadWA),
|
||||||
|
NORMALPRIO,
|
||||||
|
PollAccelThread,
|
||||||
|
NULL);
|
||||||
|
|
||||||
/* Create temperature thread */
|
/* Create temperature thread */
|
||||||
chThdCreateStatic(PollTmp75ThreadWA,
|
chThdCreateStatic(PollTmp75ThreadWA,
|
||||||
sizeof(PollTmp75ThreadWA),
|
sizeof(PollTmp75ThreadWA),
|
||||||
|
@ -111,24 +115,15 @@ int main(void) {
|
||||||
PollTmp75Thread,
|
PollTmp75Thread,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
/* Create not responding thread */
|
||||||
/* Create max1236 thread */
|
chThdCreateStatic(PollFakeThreadWA,
|
||||||
chThdCreateStatic(PollMax1236ThreadWA,
|
sizeof(PollFakeThreadWA),
|
||||||
sizeof(PollMax1236ThreadWA),
|
|
||||||
NORMALPRIO,
|
NORMALPRIO,
|
||||||
PollMax1236Thread,
|
PollFakeThread,
|
||||||
NULL);
|
|
||||||
|
|
||||||
|
|
||||||
/* Create accelerometer thread */
|
|
||||||
chThdCreateStatic(PollAccelThreadWA,
|
|
||||||
sizeof(PollAccelThreadWA),
|
|
||||||
HIGHPRIO,
|
|
||||||
PollAccelThread,
|
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/* Creates the blinker thread. */
|
/* Creates the blinker thread. */
|
||||||
chThdCreateStatic(BlinkWA, sizeof(BlinkWA), LOWPRIO, Blink, NULL);
|
chThdCreateStatic(BlinkWA, sizeof(BlinkWA), HIGHPRIO, Blink, NULL);
|
||||||
|
|
||||||
/* main loop that do nothing */
|
/* main loop that do nothing */
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
/*
|
|
||||||
* main.h
|
|
||||||
*
|
|
||||||
* Created on: 25.03.2011
|
|
||||||
* Author: barthess
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MAIN_H_
|
|
||||||
#define MAIN_H_
|
|
||||||
|
|
||||||
|
|
||||||
// ãëîáàëüíûå ôëàãè
|
|
||||||
#define GET_FILTERED_RAW_GYRO TRUE
|
|
||||||
#define GET_FILTERED_RAW_ACCEL TRUE
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* MAIN_H_ */
|
|
|
@ -1,75 +0,0 @@
|
||||||
/**
|
|
||||||
* Maxim ADC has not so suitable default settings after startup.
|
|
||||||
* So we will create init function to tune this ADC.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "ch.h"
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
#include "max1236.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define max1236_addr 0b0110100
|
|
||||||
|
|
||||||
|
|
||||||
/* Data buffers */
|
|
||||||
static i2cblock_t max1236_rx_data[MAX1236_RX_DEPTH];
|
|
||||||
static i2cblock_t max1236_tx_data[MAX1236_TX_DEPTH];
|
|
||||||
/* ADC results */
|
|
||||||
static uint16_t ch1 = 0, ch2 = 0, ch3 = 0, ch4 = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/* Error trap */
|
|
||||||
static void i2c_max1236_error_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){
|
|
||||||
(void)i2cscfg;
|
|
||||||
int status = 0;
|
|
||||||
status = i2cp->id_i2c->SR1;
|
|
||||||
while(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This callback raise up when transfer finished */
|
|
||||||
static void i2c_max1236_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){
|
|
||||||
(void)*i2cp;
|
|
||||||
(void)*i2cscfg;
|
|
||||||
/* get ADC data */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ADC maxim MAX1236 config */
|
|
||||||
|
|
||||||
static const I2CSlaveConfig max1236 = {
|
|
||||||
i2c_max1236_cb,
|
|
||||||
i2c_max1236_error_cb,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initilization routine. See datasheet on page 13 to understand
|
|
||||||
* how to initialize ADC.
|
|
||||||
*/
|
|
||||||
void init_max1236(void){
|
|
||||||
/* this data we must send via IC to setup ADC */
|
|
||||||
max1236_tx_data[0] = 0b10000011; /* config register content. Consult datasheet */
|
|
||||||
max1236_tx_data[1] = 0b00000111; /* config register content. Consult datasheet */
|
|
||||||
|
|
||||||
/* transmit out 2 bytes */
|
|
||||||
i2cAcquireBus(&I2CD2);
|
|
||||||
i2cMasterTransmit(&I2CD2, &max1236, max1236_addr, max1236_tx_data, 2, max1236_rx_data, 0);
|
|
||||||
i2cReleaseBus(&I2CD2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Now simply read 8 bytes to get all 4 ADC channels */
|
|
||||||
void read_max1236(void){
|
|
||||||
i2cAcquireBus(&I2CD2);
|
|
||||||
i2cMasterReceive(&I2CD2, &max1236, max1236_addr, max1236_rx_data, 8);
|
|
||||||
i2cReleaseBus(&I2CD2);
|
|
||||||
|
|
||||||
ch1 = ((max1236_rx_data[0] & 0xF) << 8) + max1236_rx_data[1];
|
|
||||||
ch2 = ((max1236_rx_data[2] & 0xF) << 8) + max1236_rx_data[3];
|
|
||||||
ch3 = ((max1236_rx_data[4] & 0xF) << 8) + max1236_rx_data[5];
|
|
||||||
ch4 = ((max1236_rx_data[6] & 0xF) << 8) + max1236_rx_data[7];
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
#include "ch.h"
|
|
||||||
|
|
||||||
#ifndef MAX1236_H_
|
|
||||||
#define MAX1236_H_
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX1236_RX_DEPTH 8
|
|
||||||
#define MAX1236_TX_DEPTH 2
|
|
||||||
|
|
||||||
|
|
||||||
void init_max1236(void);
|
|
||||||
void read_max1236(void);
|
|
||||||
|
|
||||||
#endif /* MAX1236_H_ */
|
|
|
@ -47,7 +47,7 @@
|
||||||
/*
|
/*
|
||||||
* ADC driver system settings.
|
* ADC driver system settings.
|
||||||
*/
|
*/
|
||||||
#define STM32_ADC_USE_ADC1 TRUE
|
#define STM32_ADC_USE_ADC1 FALSE
|
||||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||||
|
@ -122,8 +122,8 @@
|
||||||
/*
|
/*
|
||||||
* SERIAL driver system settings.
|
* SERIAL driver system settings.
|
||||||
*/
|
*/
|
||||||
#define STM32_SERIAL_USE_USART1 TRUE
|
#define STM32_SERIAL_USE_USART1 FALSE
|
||||||
#define STM32_SERIAL_USE_USART2 TRUE
|
#define STM32_SERIAL_USE_USART2 FALSE
|
||||||
#define STM32_SERIAL_USE_USART3 FALSE
|
#define STM32_SERIAL_USE_USART3 FALSE
|
||||||
#define STM32_SERIAL_USE_UART4 FALSE
|
#define STM32_SERIAL_USE_UART4 FALSE
|
||||||
#define STM32_SERIAL_USE_UART5 FALSE
|
#define STM32_SERIAL_USE_UART5 FALSE
|
||||||
|
@ -138,8 +138,8 @@
|
||||||
/*
|
/*
|
||||||
* SPI driver system settings.
|
* SPI driver system settings.
|
||||||
*/
|
*/
|
||||||
#define STM32_SPI_USE_SPI1 TRUE
|
#define STM32_SPI_USE_SPI1 FALSE
|
||||||
#define STM32_SPI_USE_SPI2 TRUE
|
#define STM32_SPI_USE_SPI2 FALSE
|
||||||
#define STM32_SPI_USE_SPI3 FALSE
|
#define STM32_SPI_USE_SPI3 FALSE
|
||||||
#define STM32_SPI_SPI1_DMA_PRIORITY 1
|
#define STM32_SPI_SPI1_DMA_PRIORITY 1
|
||||||
#define STM32_SPI_SPI2_DMA_PRIORITY 1
|
#define STM32_SPI_SPI2_DMA_PRIORITY 1
|
||||||
|
@ -167,25 +167,18 @@
|
||||||
* I2C driver system settings.
|
* I2C driver system settings.
|
||||||
*/
|
*/
|
||||||
#define STM32_I2C_USE_I2C1 TRUE
|
#define STM32_I2C_USE_I2C1 TRUE
|
||||||
#define STM32_I2C_USE_I2C2 TRUE
|
#define STM32_I2C_USE_I2C2 FALSE
|
||||||
#define STM32_I2C_I2C1_IRQ_PRIORITY 10
|
#define STM32_I2C_I2C1_IRQ_PRIORITY 10
|
||||||
#define STM32_I2C_I2C2_IRQ_PRIORITY 10
|
#define STM32_I2C_I2C2_IRQ_PRIORITY 10
|
||||||
#define STM32_I2C_I2C1_DMA_PRIORITY 4
|
#define STM32_I2C_I2C1_DMA_PRIORITY 1
|
||||||
#define STM32_I2C_I2C2_DMA_PRIORITY 4
|
#define STM32_I2C_I2C2_DMA_PRIORITY 1
|
||||||
#define STM32_I2C_I2C1_DMA_ERROR_HOOK() chSysHalt()
|
#define STM32_I2C_I2C1_DMA_ERROR_HOOK() chSysHalt()
|
||||||
#define STM32_I2C_I2C2_DMA_ERROR_HOOK() chSysHalt()
|
#define STM32_I2C_I2C2_DMA_ERROR_HOOK() chSysHalt()
|
||||||
/* I2C1 */
|
|
||||||
#define STM32_I2C_I2C1_USE_GPT_TIM GPTD1
|
|
||||||
#define STM32_I2C_I2C1_USE_POLLING_WAIT TRUE
|
|
||||||
/* I2C2 */
|
|
||||||
#define STM32_I2C_I2C2_USE_GPT_TIM GPTD2
|
|
||||||
#define STM32_I2C_I2C2_USE_POLLING_WAIT TRUE
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* USB driver system settings.
|
* USB driver system settings.
|
||||||
*/
|
*/
|
||||||
#define STM32_USB_USE_USB1 TRUE
|
#define STM32_USB_USE_USB1 FALSE
|
||||||
#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
|
#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
|
||||||
#define STM32_USB_USB1_HP_IRQ_PRIORITY 6
|
#define STM32_USB_USB1_HP_IRQ_PRIORITY 6
|
||||||
#define STM32_USB_USB1_LP_IRQ_PRIORITY 14
|
#define STM32_USB_USB1_LP_IRQ_PRIORITY 14
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||||
|
2011 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TMP75 is most simple I2C device in our case. It is already useful with
|
* TMP75 is most simple I2C device in our case. It is already useful with
|
||||||
* default settings after powerup.
|
* default settings after powerup.
|
||||||
|
@ -13,40 +33,25 @@
|
||||||
|
|
||||||
|
|
||||||
/* input buffer */
|
/* input buffer */
|
||||||
static i2cblock_t tmp75_rx_data[TMP75_RX_DEPTH];
|
static uint8_t tmp75_rx_data[TMP75_RX_DEPTH];
|
||||||
|
|
||||||
/* temperature value */
|
/* temperature value */
|
||||||
static int16_t temperature = 0;
|
static int16_t temperature = 0;
|
||||||
|
|
||||||
/* Simple error trap */
|
|
||||||
static void i2c_tmp75_error_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){
|
|
||||||
(void)i2cscfg;
|
|
||||||
int status = 0;
|
|
||||||
status = i2cp->id_i2c->SR1;
|
|
||||||
while(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This callback raise up when transfer finished */
|
|
||||||
static void i2c_tmp75_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){
|
|
||||||
(void)*i2cp;
|
|
||||||
(void)*i2cscfg;
|
|
||||||
/* store temperature value */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill TMP75 config. */
|
|
||||||
static const I2CSlaveConfig tmp75 = {
|
|
||||||
i2c_tmp75_cb,
|
|
||||||
i2c_tmp75_error_cb,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define tmp75_addr 0b1001000
|
#define tmp75_addr 0b1001000
|
||||||
|
|
||||||
/* This is main function. */
|
/* This is main function. */
|
||||||
void request_temperature(void){
|
void request_temperature(void){
|
||||||
i2cAcquireBus(&I2CD2);
|
int16_t t_int = 0, t_frac = 0;
|
||||||
i2cMasterReceive(&I2CD2, &tmp75, tmp75_addr, tmp75_rx_data, 2);
|
|
||||||
i2cReleaseBus(&I2CD2);
|
i2cAcquireBus(&I2CD1);
|
||||||
temperature = (tmp75_rx_data[0] << 8) + tmp75_rx_data[1];
|
i2cMasterReceive(&I2CD1, tmp75_addr, tmp75_rx_data, 2);
|
||||||
|
i2cReleaseBus(&I2CD1);
|
||||||
|
|
||||||
|
t_int = tmp75_rx_data[0] * 100;
|
||||||
|
t_frac = (tmp75_rx_data[1] * 100) >> 8;
|
||||||
|
temperature = t_int + t_frac;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||||
|
2011 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef TMP75_H_
|
#ifndef TMP75_H_
|
||||||
#define TMP75_H_
|
#define TMP75_H_
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue