diff options
author | barthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-05-05 17:43:54 +0000 |
---|---|---|
committer | barthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-05-05 17:43:54 +0000 |
commit | 4fda4dc84fcfcfa483f10a8b5043d124ad551ba0 (patch) | |
tree | b880dfea145a9ea6c85cc592e6d24c2a65f356c4 /os/hal/src | |
parent | 5387a1b39fdefec625c0a285ed8fd63c9baf827f (diff) | |
download | ChibiOS-4fda4dc84fcfcfa483f10a8b5043d124ad551ba0.tar.gz ChibiOS-4fda4dc84fcfcfa483f10a8b5043d124ad551ba0.tar.bz2 ChibiOS-4fda4dc84fcfcfa483f10a8b5043d124ad551ba0.zip |
I2C. Code compiles successfully, but totally not tested.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@2921 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/src')
-rw-r--r-- | os/hal/src/i2c.c | 150 |
1 files changed, 109 insertions, 41 deletions
diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index ad9a5d0ac..50767b3a9 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -130,106 +130,174 @@ void i2cStop(I2CDriver *i2cp) { }
/**
- * @brief Generate (re)start on the bus.
+ * @brief Sends data ever the I2C bus.
*
* @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] i2cscfg pointer to the @p I2C slave config
+ *
*/
-void i2cMasterStart(I2CDriver *i2cp){
+void i2cMasterTransmit(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg) {
+
+ size_t n;
+ i2cblock_t *txbuf;
+
+ txbuf = i2cscfg->txbuf;
+ n = i2cscfg->tx_remaining_bytes;
+
+ chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) && (n > 0) && (txbuf != NULL),
+ "i2cMasterTransmit");
- chDbgCheck((i2cp != NULL), "i2cMasterTransmit");
+ // init slave config field in driver
+ i2cp->id_slave_config = i2cscfg;
+
+#if I2C_USE_WAIT
+ i2c_lld_wait_bus_free(i2cp);
+ if(i2c_lld_bus_is_busy(i2cp)) {
+#ifdef PRINTTRACE
+ print("I2C Bus busy!\n");
+#endif
+ return;
+ };
+#endif
chSysLock();
- i2c_lld_master_start(i2cp);
+ chDbgAssert(i2cp->id_state == I2C_READY,
+ "i2cMasterTransmit(), #1", "not ready");
+
+ i2cp->id_state = I2C_ACTIVE;
+ i2c_lld_master_transmit(i2cp);
+ _i2c_wait_s(i2cp);
+#if !I2C_USE_WAIT
+ i2c_lld_wait_bus_free(i2cp);
+#endif
+ if (i2cp->id_state == I2C_COMPLETE)
+ i2cp->id_state = I2C_READY;
chSysUnlock();
}
/**
- * @brief Generate stop on the bus.
+ * @brief Receives data from the I2C bus.
*
* @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] i2cscfg pointer to the @p I2C slave config
+ *
*/
-void i2cMasterStop(I2CDriver *i2cp){
+void i2cMasterReceive(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg){
+
+ size_t n;
+ i2cblock_t *rxbuf;
+
+ rxbuf = i2cscfg->rxbuf;
+ n = i2cscfg->rx_remaining_bytes;
+
+ chDbgCheck((i2cp != NULL) && (n > 0) && (rxbuf != NULL),
+ "i2cMasterReceive");
+
+ // init slave config field in driver
+ i2cp->id_slave_config = i2cscfg;
+
+#if I2C_USE_WAIT
+ i2c_lld_wait_bus_free(i2cp);
+ if(i2c_lld_bus_is_busy(i2cp)) {
+#ifdef PRINTTRACE
+ print("I2C Bus busy!\n");
+#endif
+ return;
+ };
+#endif
- chDbgCheck((i2cp != NULL), "i2cMasterTransmit");
chSysLock();
- i2c_lld_master_stop(i2cp);
+ chDbgAssert(i2cp->id_state == I2C_READY,
+ "i2cMasterReceive(), #1", "not ready");
+
+ i2cp->id_state = I2C_ACTIVE;
+ i2c_lld_master_receive(i2cp);
+ _i2c_wait_s(i2cp);
+#if !I2C_USE_WAIT
+ i2c_lld_wait_bus_free(i2cp);
+#endif
+ if (i2cp->id_state == I2C_COMPLETE)
+ i2cp->id_state = I2C_READY;
chSysUnlock();
}
+uint16_t i2cSMBusAlertResponse(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg) {
+
+ i2cMasterReceive(i2cp, i2cscfg);
+ return i2cp->id_slave_config->slave_addr;
+}
+
+
/**
- * @brief Sends data ever the I2C bus.
+ * @brief Handles communication events/errors.
+ * @details Must be called from the I/O interrupt service routine in order to
+ * notify I/O conditions as errors, signals change etc.
*
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object
+ * @param[in] i2cp pointer to a @p I2CDriver structure
+ * @param[in] mask condition flags to be added to the mask
*
+ * @iclass
*/
-void i2cMasterTransmit(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg) {
+void i2cAddFlagsI(I2CDriver *i2cp, i2cflags_t mask) {
- chDbgCheck((i2cp != NULL) && (i2cscfg != NULL),
- "i2cMasterTransmit");
- chDbgAssert(i2cp->id_state == I2C_READY,
- "i2cMasterTransmit(), #1",
- "not active");
+ chDbgCheck(i2cp != NULL, "i2cAddFlagsI");
- chSysLock();
- i2c_lld_master_transmit(i2cp, i2cscfg);
- chSysUnlock();
+ i2cp->id_slave_config->errors |= mask;
+ chEvtBroadcastI(&i2cp->id_slave_config->sevent);
}
-
/**
- * @brief Receives data from the I2C bus.
+ * @brief Returns and clears the errors mask associated to the driver.
*
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object
+ * @param[in] i2cp pointer to a @p I2CDriver structure
+ * @return The condition flags modified since last time this
+ * function was invoked.
+ *
+ * @api
*/
-void i2cMasterReceive(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg) {
+i2cflags_t i2cGetAndClearFlags(I2CDriver *i2cp) {
+ i2cflags_t mask;
- chDbgCheck((i2cp != NULL) && (i2cscfg != NULL),
- "i2cMasterReceive");
- chDbgAssert(i2cp->id_state == I2C_READY,
- "i2cMasterReceive(), #1",
- "not active");
+ chDbgCheck(i2cp != NULL, "i2cGetAndClearFlags");
chSysLock();
- i2c_lld_master_receive(i2cp, i2cscfg);
+ mask = i2cp->id_slave_config->errors;
+ i2cp->id_slave_config->errors = I2CD_NO_ERROR;
chSysUnlock();
+ return mask;
}
#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
/**
- * @brief Gains exclusive access to the I2C bus.
+ * @brief Gains exclusive access to the I2C bus.
* @details This function tries to gain ownership to the I2C 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
- *
+ * @note This function is only available when the @p I2C_USE_MUTUAL_EXCLUSION
+ * option is set to @p TRUE.
*/
void i2cAcquireBus(I2CDriver *i2cp) {
chDbgCheck(i2cp != NULL, "i2cAcquireBus");
#if CH_USE_MUTEXES
- chMtxLock(&i2cp->id_mutex);
+ chMtxLock(&i2cp->mutex);
#elif CH_USE_SEMAPHORES
chSemWait(&i2cp->id_semaphore);
#endif
}
/**
- * @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.
+ * @brief Releases exclusive access to the I2C bus.
*
* @param[in] i2cp pointer to the @p I2CDriver object
*
- * @api
+ * @note This function is only available when the @p I2C_USE_MUTUAL_EXCLUSION
+ * option is set to @p TRUE.
*/
void i2cReleaseBus(I2CDriver *i2cp) {
|