Merge pull request #308 from ChibiOS/chibios-20.3.x
Modified i2c peripheral configuration
This commit is contained in:
commit
0323f2f492
|
@ -94,12 +94,14 @@ void _pal_lld_setgroupmode(ioportid_t port, ioportmask_t mask, iomode_t mode) {
|
|||
uint32_t ospeedr = (mode & PAL_WB32_OSPEED_MASK) >> 3;
|
||||
uint32_t pupdr = (mode & PAL_WB32_PUPDR_MASK) >> 5;
|
||||
uint32_t altr = (mode & PAL_WB32_ALTERNATE_MASK) >> 7;
|
||||
uint32_t current = (mode & PAL_WB32_CURRENT_MASK) >> 11;
|
||||
|
||||
port->CFGMSK = ~mask;
|
||||
port->MODER = (moder & 0x3) * 0x55555555U;
|
||||
port->OTYPER = (otyper & 0x1) * 0xFFFFFFFFU;
|
||||
port->OSPEEDR = (ospeedr & 0x3) * 0x55555555U;
|
||||
port->PUPDR = (pupdr & 0x3) * 0x55555555U;
|
||||
port->CURRENT = (current & 0x03) * 0x55555555U;
|
||||
|
||||
tmp = altr * 0x11111111U;
|
||||
port->AFRL = tmp;
|
||||
|
|
|
@ -70,6 +70,12 @@
|
|||
#define PAL_WB32_ALTERNATE_MASK (15U << 7U)
|
||||
#define PAL_WB32_ALTERNATE(n) ((n) << 7U)
|
||||
|
||||
#define PAL_WB32_CURRENT_MASK (3U << 11U)
|
||||
#define PAL_WB32_CURRENT_LEVEL0 (0U << 11U)
|
||||
#define PAL_WB32_CURRENT_LEVEL1 (1U << 11U)
|
||||
#define PAL_WB32_CURRENT_LEVEL2 (2U << 11U)
|
||||
#define PAL_WB32_CURRENT_LEVEL3 (3U << 11U)
|
||||
|
||||
/**
|
||||
* @brief Alternate function.
|
||||
*
|
||||
|
|
|
@ -106,25 +106,51 @@ static void i2c_lld_abort_operation(I2CDriver *i2cp) {
|
|||
* @notapi
|
||||
*/
|
||||
static void i2c_lld_configuration(I2CDriver *i2cp) {
|
||||
I2C_TypeDef *dp = i2cp->i2c;
|
||||
const I2CConfig *cfg = i2cp->config;
|
||||
I2C_TypeDef *dp = i2cp->i2c;
|
||||
float tclk, tval;
|
||||
uint32_t con_reg;
|
||||
i2copmode_t opmode = i2cp->config->op_mode;
|
||||
int32_t clock_speed = i2cp->config->clock_speed;
|
||||
|
||||
osalDbgCheck((i2cp != NULL) && (dp != NULL) && (cfg != NULL));
|
||||
osalDbgCheck((i2cp != NULL) &&
|
||||
(clock_speed > 0) &&
|
||||
(clock_speed <= 400000));
|
||||
|
||||
dp->INTR_MASK |= (uint16_t)cfg->i2c_it;
|
||||
con_reg = I2C_CON_SLAVE_DISABLE | I2C_CON_RESTART_EN | I2C_CON_MASTER_MODE;
|
||||
|
||||
dp->CON = (uint32_t)cfg->op_mode;
|
||||
dp->TX_TL = 0;
|
||||
dp->RX_TL = 0;
|
||||
|
||||
dp->TAR = (uint32_t)cfg->target_address;
|
||||
switch (opmode) {
|
||||
case OPMODE_I2C:
|
||||
break;
|
||||
case OPMODE_SMBUS_DEVICE:
|
||||
osalDbgAssert(false, "SMBUS_DEVICE mode is not supported");
|
||||
break;
|
||||
case OPMODE_SMBUS_HOST:
|
||||
osalDbgAssert(false, "SMBUS_HOST mode is not supported");
|
||||
break;
|
||||
}
|
||||
|
||||
dp->TX_TL = (uint8_t)cfg->tx_fifo_threshold;
|
||||
dp->RX_TL = (uint8_t)cfg->rx_fifo_threshold;
|
||||
dp->FS_SPKLEN = (uint32_t)(WB32_PCLK2 / 1000000 * 0.02); // 20ns
|
||||
dp->SDA_HOLD = (uint32_t)(WB32_PCLK2 / 1000000 * 0.31); // 310ns
|
||||
tclk = (float)1000000 / (clock_speed << 1);
|
||||
tval = (float)WB32_PCLK2 / 1000000 * tclk;
|
||||
|
||||
dp->SS_SCL_HCNT = (uint32_t)cfg->ss_scl_hcnt;
|
||||
dp->SS_SCL_LCNT = (uint32_t)cfg->ss_scl_lcnt;
|
||||
dp->FS_SPKLEN = (uint32_t)cfg->fs_spklen;
|
||||
dp->SDA_SETUP = (uint32_t)cfg->sda_setup;
|
||||
dp->SDA_HOLD = (uint32_t)cfg->sda_hold;
|
||||
if (clock_speed <= 100000) {
|
||||
con_reg |= I2C_CON_SPEED_STANDARD;
|
||||
dp->SDA_SETUP = (uint32_t)(WB32_PCLK2 / 1000000 * 0.25); // 250ns
|
||||
dp->SS_SCL_HCNT = (uint32_t)(tval - 7 - dp->FS_SPKLEN);
|
||||
dp->SS_SCL_LCNT = (uint32_t)(tval - 1);
|
||||
}
|
||||
else if (clock_speed <= 400000) {
|
||||
con_reg |= I2C_CON_SPEED_FAST;
|
||||
dp->SDA_SETUP = (uint32_t)(WB32_PCLK2 / 1000000 * 0.15); // 150ns
|
||||
dp->FS_SCL_HCNT = (uint32_t)(tval - 7 - dp->FS_SPKLEN);
|
||||
dp->FS_SCL_LCNT = (uint32_t)(tval - 1);
|
||||
}
|
||||
|
||||
dp->CON = con_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -427,7 +453,8 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
|||
/* Disable all I2C interrupt.*/
|
||||
dp->INTR_MASK &= ~(0xFFFF);
|
||||
/* Enable the selected I2C interrupt.*/
|
||||
dp->INTR_MASK |= (i2cp->config->i2c_it);
|
||||
dp->INTR_MASK |= I2C_INTR_TX_EMPTY | I2C_INTR_TX_ABRT |
|
||||
I2C_INTR_STOP_DET | I2C_INTR_RX_FULL;
|
||||
|
||||
/* Waits for the operation completion or a timeout.*/
|
||||
msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
|
||||
|
@ -502,7 +529,8 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
|||
/* Disable all I2C interrupt.*/
|
||||
dp->INTR_MASK &= ~(0xFFFF);
|
||||
/* Enable the selected I2C interrupt.*/
|
||||
dp->INTR_MASK |= (i2cp->config->i2c_it);
|
||||
dp->INTR_MASK |= I2C_INTR_TX_EMPTY | I2C_INTR_TX_ABRT |
|
||||
I2C_INTR_STOP_DET | I2C_INTR_RX_FULL;
|
||||
|
||||
/* Waits for the operation completion or a timeout.*/
|
||||
msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
|
||||
|
|
|
@ -136,32 +136,22 @@ typedef struct {
|
|||
volatile uint32_t rx_cmd_len;
|
||||
uint32_t tx_abrt_source;
|
||||
} i2c_xfer_info_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
OPMODE_I2C = 1,
|
||||
OPMODE_SMBUS_DEVICE = 2,
|
||||
OPMODE_SMBUS_HOST = 3,
|
||||
} i2copmode_t;
|
||||
|
||||
/**
|
||||
* @brief Type of I2C driver configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/* End of the mandatory fields.*/
|
||||
/* specifies the I2C interrupt source.*/
|
||||
uint16_t i2c_it;
|
||||
/* Specifies the I2C mode.*/
|
||||
uint32_t op_mode;
|
||||
/* In host mode set the slave address */
|
||||
uint32_t target_address;
|
||||
/* The Transmit FIFO threshold to set.*/
|
||||
uint8_t tx_fifo_threshold;
|
||||
/* The Receive FIFO threshold to set.*/
|
||||
uint8_t rx_fifo_threshold;
|
||||
/* tHIGH = (ss_scl_hcnt + FS_SPKLEN + 7) / PCLK2.*/
|
||||
uint32_t ss_scl_hcnt;
|
||||
/* tLOW = (ss_scl_lcnt + 1) / PCLK2.*/
|
||||
uint32_t ss_scl_lcnt;
|
||||
/* fs_spklen / PCLK2.*/
|
||||
uint32_t fs_spklen;
|
||||
/* tSU;DAT = sda_setup / PCLK2.*/
|
||||
uint32_t sda_setup;
|
||||
/* tHD;DAT = sda_hold / PCLK2.*/
|
||||
uint32_t sda_hold;
|
||||
/* End of the mandatory fields.*/
|
||||
i2copmode_t op_mode; /**< @brief Specifies the I2C mode. */
|
||||
uint32_t clock_speed; /**< @brief Specifies the clock frequency.
|
||||
@note Must be set to a value lower
|
||||
than 400kHz. */
|
||||
} I2CConfig;
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue