git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10055 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
2689848803
commit
705d726932
|
@ -30,6 +30,11 @@
|
||||||
/* Driver local definitions. */
|
/* Driver local definitions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define CHECK_ERROR(msg) \
|
||||||
|
if ((msg) < (msg_t)0) { \
|
||||||
|
return MSG_TIMEOUT; \
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver constants. */
|
/* Driver constants. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -66,6 +71,100 @@ I2CDriver I2CD4;
|
||||||
/* Driver local functions. */
|
/* Driver local functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
static msg_t i2c_delay(I2CDriver *i2cp) {
|
||||||
|
|
||||||
|
if (!osalOsIsTimeWithinX(osalOsGetSystemTimeX(), i2cp->start, i2cp->end)) {
|
||||||
|
return MSG_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SW_I2C_USE_OSAL_DELAY || defined(__DOXYGEN__)
|
||||||
|
osalThreadSleep(i2cp->config->ticks);
|
||||||
|
#else
|
||||||
|
i2cp->config->delay();
|
||||||
|
#endif
|
||||||
|
return MSG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static msg_t i2c_write_start(I2CDriver *i2cp) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static msg_t i2c_write_restart(I2CDriver *i2cp) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static msg_t i2c_write_stop(I2CDriver *i2cp) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static msg_t i2c_writebit(I2CDriver *i2cp, unsigned bit) {
|
||||||
|
|
||||||
|
palWriteLine(i2cp->config->sda, bit);
|
||||||
|
CHECK_ERROR(i2c_delay(i2cp));
|
||||||
|
palSetLine(i2cp->config->scl);
|
||||||
|
CHECK_ERROR(i2c_delay(i2cp));
|
||||||
|
|
||||||
|
/* Clock stretching.*/
|
||||||
|
while (palReadLine(i2cp->config->scl) == PAL_LOW) {
|
||||||
|
CHECK_ERROR(i2c_delay(i2cp));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Arbitration check.*/
|
||||||
|
if ((bit == PAL_HIGH) && (palReadLine(i2cp->config->sda) == PAL_LOW)) {
|
||||||
|
i2cp->errors |= I2C_ARBITRATION_LOST;
|
||||||
|
return MSG_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
palClearLine(i2cp->config->scl);
|
||||||
|
|
||||||
|
return MSG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static msg_t i2c_readbit(I2CDriver *i2cp) {
|
||||||
|
msg_t bit;
|
||||||
|
|
||||||
|
palSetLine(i2cp->config->sda);
|
||||||
|
CHECK_ERROR(i2c_delay(i2cp));
|
||||||
|
palSetLine(i2cp->config->scl);
|
||||||
|
|
||||||
|
/* Clock stretching.*/
|
||||||
|
while (palReadLine(i2cp->config->scl) == PAL_LOW) {
|
||||||
|
CHECK_ERROR(i2c_delay(i2cp));
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_ERROR(i2c_delay(i2cp));
|
||||||
|
bit = palReadLine(i2cp->config->sda);
|
||||||
|
palClearLine(i2cp->config->scl);
|
||||||
|
|
||||||
|
return bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static msg_t i2c_writebyte(I2CDriver *i2cp, uint8_t byte) {
|
||||||
|
uint8_t mask;
|
||||||
|
|
||||||
|
for (mask = 0x80U; mask > 0U; mask >>= 1U) {
|
||||||
|
CHECK_ERROR(i2c_writebit(i2cp, (byte & mask) != 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return i2c_readbit(i2cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static msg_t i2c_readbyte(I2CDriver *i2cp, unsigned nack) {
|
||||||
|
msg_t byte;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
byte = 0U;
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
msg_t msg = i2c_readbit(i2cp);
|
||||||
|
CHECK_ERROR(msg);
|
||||||
|
byte = (byte << 1U) | msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_ERROR(i2c_writebit(i2cp, PAL_LOW));
|
||||||
|
|
||||||
|
return byte;
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver interrupt handlers. */
|
/* Driver interrupt handlers. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
|
@ -39,6 +39,16 @@
|
||||||
* @name Configuration options
|
* @name Configuration options
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* @brief Use OSAL delays.
|
||||||
|
* @details If set to @p TRUE then delays are implemented using the
|
||||||
|
* thread-friendy delay function else a delay function must
|
||||||
|
* be provided extenally.
|
||||||
|
*/
|
||||||
|
#if !defined(SW_I2C_USE_OSAL_DELAY) || defined(__DOXYGEN__)
|
||||||
|
#define SW_I2C_USE_OSAL_DELAY 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.
|
||||||
|
@ -94,10 +104,34 @@ typedef uint16_t i2caddr_t;
|
||||||
*/
|
*/
|
||||||
typedef uint8_t i2cflags_t;
|
typedef uint8_t i2cflags_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of a delay function.
|
||||||
|
*/
|
||||||
|
typedef void (*i2c_delay_t)(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type of I2C driver configuration structure.
|
* @brief Type of I2C driver configuration structure.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief I2C clock line.
|
||||||
|
*/
|
||||||
|
ioline_t scl;
|
||||||
|
/**
|
||||||
|
* @brief I2C data line.
|
||||||
|
*/
|
||||||
|
ioline_t sda;
|
||||||
|
#if SW_I2C_USE_OSAL_DELAY || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Delay of an half bit time in system ticks.
|
||||||
|
*/
|
||||||
|
systime_t ticks;
|
||||||
|
#else
|
||||||
|
/**
|
||||||
|
* @brief Pointer to an externally defined delay function.
|
||||||
|
*/
|
||||||
|
i2c_delay_t delay;
|
||||||
|
#endif
|
||||||
} I2CConfig;
|
} I2CConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,13 +163,13 @@ struct I2CDriver {
|
||||||
#endif
|
#endif
|
||||||
/* End of the mandatory fields.*/
|
/* End of the mandatory fields.*/
|
||||||
/**
|
/**
|
||||||
* @brief I2C clock line.
|
* @brief Time of operation begin.
|
||||||
*/
|
*/
|
||||||
ioline_t clk;
|
systime_t start;
|
||||||
/**
|
/**
|
||||||
* @brief I2C data line.
|
* @brief Time of operation timeout.
|
||||||
*/
|
*/
|
||||||
ioline_t data;
|
systime_t end;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
Loading…
Reference in New Issue