/* * Copyright (c) 2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ /** * @file I2C/TWI Controller driver for Atmel SAM3 family processor * * @deprecated This driver is deprecated. Please use i2c_sam_twi.c SAM family * driver instead. * * Notes on this driver: * 1. The controller does not have a documented way to * issue RESTART when changing transfer direction as master. * * Datasheet said about using the internal address register * (IADR) to write 3 bytes before reading. This limits * the number of bytes to write before a read. Also, * this was documented under 7-bit addressing, and nothing * about this with 10-bit addressing. * * Experiments show that STOP has to be issued or the controller * hangs forever. This was tested with reading and writing * the Fujitsu I2C-based FRAM MB85RC256V. */ #include #include #include #include #include #define LOG_LEVEL CONFIG_I2C_LOG_LEVEL #include LOG_MODULE_REGISTER(i2c_atmel_sam3); #define TWI_IRQ_PDC \ (TWI_SR_ENDRX | TWI_SR_ENDTX | TWI_SR_RXBUFF | TWI_SR_TXBUFE) /* for use with dev_data->state */ #define STATE_READY 0 #define STATE_BUSY (1 << 0) #define STATE_TX (1 << 1) #define STATE_RX (1 << 2) /* return values for internal functions */ #define RET_OK 0 #define RET_ERR 1 #define RET_NACK 2 typedef void (*config_func_t)(struct device *dev); struct i2c_sam3_dev_config { Twi *regs; config_func_t config_func; }; struct i2c_sam3_dev_data { struct k_sem device_sync_sem; u32_t dev_config; volatile u32_t state; u8_t *xfr_buf; u32_t xfr_len; u32_t xfr_flags; }; /** * Calculate clock dividers for TWI controllers. * * @param dev Device struct * @return Value used for TWI_CWGR register. */ static u32_t clk_div_calc(struct device *dev) { #if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 84000000) /* Use pre-calculated clock dividers when the SoC is running at * 84 MHz. This saves execution time and ROM space. */ struct i2c_sam3_dev_data * const dev_data = dev->driver_data; switch (I2C_SPEED_GET(dev_data->dev_config)) { case I2C_SPEED_STANDARD: /* CKDIV = 1 * CHDIV = CLDIV = 208 = 0xD0 */ return 0x0001D0D0; case I2C_SPEED_FAST: /* CKDIV = 0 * CHDIV = 101 = 0x65 * CLDIV = 106 = 0x6A */ return 0x0000656A; default: /* Return 0 as error */ return 0; } #else /* !(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 84000000) */ /* Need to calcualte the clock dividers if the SoC is running at * other frequencies. */ struct i2c_sam3_dev_data * const dev_data = dev->driver_data; u32_t i2c_clk; u32_t cldiv, chdiv, ckdiv; u32_t i2c_h_min_time, i2c_l_min_time; u32_t cldiv_min, chdiv_min; u32_t mck; /* The T(low) and T(high) are used to calculate CLDIV and CHDIV. * Since we treat both clock low and clock high to have same period, * the I2C clock frequency used for calculation has to be doubled. * * The I2C spec has the following minimum timing requirement: * Standard Speed: High 4000ns, Low 4700ns * Fast Speed: High 600ns, Low 1300ns * * So use these to calculate chdiv_min and cldiv_min. */ switch (I2C_SPEED_GET(dev_data->dev_config)) { case I2C_SPEED_STANDARD: i2c_clk = 100000 * 2; i2c_h_min_time = 4000; i2c_l_min_time = 4700; break; case I2C_SPEED_FAST: i2c_clk = 400000 * 2; i2c_h_min_time = 600; i2c_l_min_time = 1300; break; default: /* Return 0 as error */ return 0; } /* Calculate CLDIV (which will be used for CHDIV also) */ cldiv = (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) / i2c_clk - 4; /* Calculate minimum CHDIV and CLDIV */ /* Make 1/mck be in micro second */ mck = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / MSEC_PER_SEC / USEC_PER_MSEC; /* The +1 is to make sure we don't go under the minimum * after the division. In other words, force rounding up. */ cldiv_min = (i2c_l_min_time * mck / 1000) - 4 + 1; chdiv_min = (i2c_h_min_time * mck / 1000) - 4 + 1; ckdiv = 0; while (cldiv > 255) { ckdiv++; /* Math is there to round up. * Rounding up makes the SCL periods longer, * which makes clock slower. * This is fine as faster clock may cause * issues. */ cldiv = (cldiv >> 1) + (cldiv & 0x01); cldiv_min = (cldiv_min >> 1) + (cldiv_min & 0x01); chdiv_min = (chdiv_min >> 1) + (chdiv_min & 0x01); } chdiv = cldiv; /* Make sure we are above minimum requirements */ cldiv = max(cldiv, cldiv_min); chdiv = max(chdiv, chdiv_min); return TWI_CWGR_CKDIV(ckdiv) + TWI_CWGR_CHDIV(chdiv) + TWI_CWGR_CLDIV(cldiv); #endif /* CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 84000000 */ } static int i2c_sam3_runtime_configure(struct device *dev, u32_t config) { const struct i2c_sam3_dev_config * const cfg = dev->config->config_info; struct i2c_sam3_dev_data * const dev_data = dev->driver_data; u32_t reg; u32_t clk; dev_data->dev_config = config; reg = 0; /* Calculate clock dividers */ clk = clk_div_calc(dev); if (!clk) { return -EINVAL; } /* Disable controller first before changing anything */ cfg->regs->TWI_CR = TWI_CR_MSDIS | TWI_CR_SVDIS; /* Setup clock wavefore generator */ cfg->regs->TWI_CWGR = clk; return 0; } static void i2c_sam3_isr(void *arg) { struct device * const dev = (struct device *)arg; const struct i2c_sam3_dev_config *const cfg = dev->config->config_info; struct i2c_sam3_dev_data * const dev_data = dev->driver_data; /* Disable all interrupts so they can be processed * before ISR is called again. */ cfg->regs->TWI_IDR = cfg->regs->TWI_IMR; k_sem_give(&dev_data->device_sync_sem); } /* This should be used ONLY IF are the only bits of concern. * This is because reading from status register will clear certain * bits, and thus status might be ignored afterwards. */ static inline void sr_bits_set_wait(struct device *dev, u32_t bits) { const struct i2c_sam3_dev_config *const cfg = dev->config->config_info; while (!(cfg->regs->TWI_SR & bits)) { /* loop till are set */ } } /* Clear the status registers from previous transfers */ static inline void status_reg_clear(struct device *dev) { const struct i2c_sam3_dev_config *const cfg = dev->config->config_info; u32_t stat_reg; do { stat_reg = cfg->regs->TWI_SR; /* ignore these */ stat_reg &= ~(TWI_IRQ_PDC | TWI_SR_TXRDY | TWI_SR_TXCOMP | TWI_SR_SVREAD); if (stat_reg & TWI_SR_OVRE) { continue; } if (stat_reg & TWI_SR_NACK) { continue; } if (stat_reg & TWI_SR_RXRDY) { stat_reg = cfg->regs->TWI_RHR; } } while (stat_reg); } static inline void transfer_setup(struct device *dev, u16_t slave_address) { const struct i2c_sam3_dev_config *const cfg = dev->config->config_info; struct i2c_sam3_dev_data * const dev_data = dev->driver_data; u32_t mmr; u32_t iadr; /* Set slave address */ if (I2C_ADDR_10_BITS & dev_data->dev_config) { /* 10-bit slave addressing: * first two bits goes to MMR/DADR, other 8 to IADR. * * 0x78 is the 0b11110xx bit prefix. */ mmr = TWI_MMR_DADR(0x78 | ((slave_address >> 8) & 0x03)); mmr |= TWI_MMR_IADRSZ_1_BYTE; iadr = slave_address & 0xFF; } else { /* 7-bit slave addressing */ mmr = TWI_MMR_DADR(slave_address); iadr = 0; } cfg->regs->TWI_MMR = mmr; cfg->regs->TWI_IADR = iadr; } static inline int msg_write(struct device *dev) { const struct i2c_sam3_dev_config *const cfg = dev->config->config_info; struct i2c_sam3_dev_data * const dev_data = dev->driver_data; /* To write to slave */ cfg->regs->TWI_MMR &= ~TWI_MMR_MREAD; /* Setup PDC to do DMA transfer */ cfg->regs->TWI_PTCR = TWI_PTCR_TXTDIS | TWI_PTCR_RXTDIS; cfg->regs->TWI_TPR = (u32_t)dev_data->xfr_buf; cfg->regs->TWI_TCR = dev_data->xfr_len; /* Enable TX related interrupts. * TXRDY is used by PDC so we don't want to interfere. */ cfg->regs->TWI_IER = TWI_SR_ENDTX | TWI_SR_NACK; /* Start DMA transfer for TX */ cfg->regs->TWI_PTCR = TWI_PTCR_TXTEN; /* Wait till transfer is done or error occurs */ k_sem_take(&dev_data->device_sync_sem, K_FOREVER); /* Check for error */ if (cfg->regs->TWI_SR & TWI_SR_NACK) { return RET_NACK; } /* STOP if needed */ if (dev_data->xfr_flags & I2C_MSG_STOP) { cfg->regs->TWI_CR = TWI_CR_STOP; /* Wait for TXCOMP if sending STOP. * The transfer is done and the controller just needs to * 'send' the STOP bit. So wait should be very short. */ sr_bits_set_wait(dev, TWI_SR_TXCOMP); } else { /* If no STOP, just wait for TX buffer to clear. * At this point, this should take no time. */ sr_bits_set_wait(dev, TWI_SR_TXRDY); } /* Disable PDC */ cfg->regs->TWI_PTCR = TWI_PTCR_TXTDIS; return RET_OK; } static inline int msg_read(struct device *dev) { const struct i2c_sam3_dev_config *const cfg = dev->config->config_info; struct i2c_sam3_dev_data * const dev_data = dev->driver_data; u32_t stat_reg; u32_t ctrl_reg; u32_t last_len; /* To read from slave */ cfg->regs->TWI_MMR |= TWI_MMR_MREAD; /* START bit in control register needs to be set to start * reading from slave. If the previous message is also read, * there is no need to set the START bit again. */ ctrl_reg = 0; if (dev_data->xfr_flags & I2C_MSG_RESTART) { ctrl_reg = TWI_CR_START; } /* If there is only one byte to read, need to send STOP also. */ if ((dev_data->xfr_len == 1) && (dev_data->xfr_flags & I2C_MSG_STOP)) { ctrl_reg |= TWI_CR_STOP; dev_data->xfr_flags &= ~I2C_MSG_STOP; } cfg->regs->TWI_CR = ctrl_reg; /* Note that this is entirely possible to do the last byte without * going through DMA. But that requires another block of code to * setup the transfer and test for RXRDY bit (and other). So do it * this way to save a few bytes of code space. */ while (dev_data->xfr_len > 0) { /* Setup PDC to do DMA transfer. */ cfg->regs->TWI_PTCR = TWI_PTCR_TXTDIS | TWI_PTCR_RXTDIS; cfg->regs->TWI_RPR = (u32_t)dev_data->xfr_buf; /* Note that we need to set the STOP bit before reading * last byte from RHR. So we need to process the last byte * differently. */ if (dev_data->xfr_len > 1) { last_len = dev_data->xfr_len - 1; } else { last_len = 1; /* Set STOP bit for last byte. * The extra check here is to prevent setting * TWI_CR_STOP twice, when the message length * is 1, as it is already set above. */ if (dev_data->xfr_flags & I2C_MSG_STOP) { cfg->regs->TWI_CR = TWI_CR_STOP; } } cfg->regs->TWI_RCR = last_len; /* Start DMA transfer for RX */ cfg->regs->TWI_PTCR = TWI_PTCR_RXTEN; /* Enable RX related interrupts * RXRDY is used by PDC so we don't want to interfere. */ cfg->regs->TWI_IER = TWI_SR_ENDRX | TWI_SR_NACK | TWI_SR_OVRE; /* Wait till transfer is done or error occurs */ k_sem_take(&dev_data->device_sync_sem, K_FOREVER); /* Check for errors */ stat_reg = cfg->regs->TWI_SR; if (stat_reg & TWI_SR_NACK) { return RET_NACK; } if (stat_reg & TWI_SR_OVRE) { return RET_ERR; } /* no more bytes to send */ if (dev_data->xfr_len == 0) { break; } dev_data->xfr_buf += last_len; dev_data->xfr_len -= last_len; } /* Disable PDC */ cfg->regs->TWI_PTCR = TWI_PTCR_RXTDIS; /* TXCOMP is kind of misleading here. This bit is set when THR/RHR * and all shift registers are empty, and STOP (or NACK) is detected. * So we wait here. */ sr_bits_set_wait(dev, TWI_SR_TXCOMP); return RET_OK; } static int i2c_sam3_transfer(struct device *dev, struct i2c_msg *msgs, u8_t num_msgs, u16_t slave_address) { const struct i2c_sam3_dev_config *const cfg = dev->config->config_info; struct i2c_sam3_dev_data * const dev_data = dev->driver_data; struct i2c_msg *cur_msg = msgs; u8_t msg_left = num_msgs; u32_t pflags = 0; int ret = 0; int xfr_ret; __ASSERT_NO_MSG(msgs); if (!num_msgs) { return 0; } /* Device is busy servicing another transfer */ if (dev_data->state & STATE_BUSY) { return -EIO; } dev_data->state = STATE_BUSY; /* Need to clear status from previous transfers */ status_reg_clear(dev); /* Enable master */ cfg->regs->TWI_CR = TWI_CR_MSEN | TWI_CR_SVDIS; transfer_setup(dev, slave_address); /* Process all messages one-by-one */ while (msg_left > 0) { dev_data->xfr_buf = cur_msg->buf; dev_data->xfr_len = cur_msg->len; dev_data->xfr_flags = cur_msg->flags; /* Send STOP if this is the last message */ if (msg_left == 1) { dev_data->xfr_flags |= I2C_MSG_STOP; } /* The controller does not have a documented way to * issue RESTART when changing transfer direction as master. * * Datasheet said about using the internal address register * (IADR) to write 3 bytes before reading. This limits * the number of bytes to write before a read. Also, * this was documented under 7-bit addressing, and nothing * about this with 10-bit addressing. * * Experiments show that STOP has to be issued or * the controller hangs forever. */ if (msg_left > 1) { if ((dev_data->xfr_flags & I2C_MSG_RW_MASK) != (cur_msg[1].flags & I2C_MSG_RW_MASK)) { dev_data->xfr_flags |= I2C_MSG_STOP; } } /* The RESTART flag is used to indicate whether to set * the START bit in control register. This is used only * when changing from write to read, as the START needs * to be set to start receiving. This is also to avoid * setting the START bit multiple time if we are doing * multiple read messages in a roll. */ if ((dev_data->xfr_flags & I2C_MSG_RW_MASK) != (pflags & I2C_MSG_RW_MASK)) { dev_data->xfr_flags |= I2C_MSG_RESTART; } dev_data->state &= ~(STATE_TX | STATE_RX); if ((dev_data->xfr_flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) { dev_data->state |= STATE_TX; xfr_ret = msg_write(dev); } else { dev_data->state |= STATE_RX; xfr_ret = msg_read(dev); } if (xfr_ret == RET_NACK) { /* Disable PDC if NACK is received. */ cfg->regs->TWI_PTCR = TWI_PTCR_TXTDIS | TWI_PTCR_RXTDIS; ret = -EIO; goto done; } if (xfr_ret == RET_ERR) { /* Error encountered: * Reset the controller and configure it again. */ cfg->regs->TWI_PTCR = TWI_PTCR_TXTDIS | TWI_PTCR_RXTDIS; cfg->regs->TWI_CR = TWI_CR_SWRST | TWI_CR_MSDIS | TWI_CR_SVDIS; i2c_sam3_runtime_configure(dev, dev_data->dev_config); ret = -EIO; goto done; } cur_msg++; msg_left--; pflags = cur_msg->flags; } done: dev_data->state = STATE_READY; /* Disable master and slave after transfer is done */ cfg->regs->TWI_CR = TWI_CR_MSDIS | TWI_CR_SVDIS; return ret; } static const struct i2c_driver_api api_funcs = { .configure = i2c_sam3_runtime_configure, .transfer = i2c_sam3_transfer, }; static int __deprecated i2c_sam3_init(struct device *dev) { const struct i2c_sam3_dev_config * const cfg = dev->config->config_info; struct i2c_sam3_dev_data * const dev_data = dev->driver_data; k_sem_init(&dev_data->device_sync_sem, 0, UINT_MAX); /* Disable all interrupts */ cfg->regs->TWI_IDR = cfg->regs->TWI_IMR; cfg->config_func(dev); if (i2c_sam3_runtime_configure(dev, dev_data->dev_config) != 0) { LOG_DBG("I2C: Cannot set default configuration 0x%x", dev_data->dev_config); return -EINVAL; } return 0; } #ifdef CONFIG_I2C_0 static void config_func_0(struct device *dev); static const struct i2c_sam3_dev_config dev_config_0 = { .regs = TWI0, .config_func = config_func_0, }; static struct i2c_sam3_dev_data dev_data_0 = { .dev_config = CONFIG_I2C_0_DEFAULT_CFG, }; DEVICE_AND_API_INIT(i2c_sam3_0, CONFIG_I2C_0_NAME, &i2c_sam3_init, &dev_data_0, &dev_config_0, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &api_funcs); static void config_func_0(struct device *dev) { /* Enable clock for TWI0 controller */ PMC->PMC_PCER0 = (1 << ID_TWI0); IRQ_CONNECT(TWI0_IRQn, DT_I2C_0_IRQ_PRI, i2c_sam3_isr, DEVICE_GET(i2c_sam3_0), 0); irq_enable(TWI0_IRQn); } #endif /* CONFIG_I2C_0 */ #ifdef CONFIG_I2C_1 static void config_func_1(struct device *dev); static const struct i2c_sam3_dev_config dev_config_1 = { .regs = TWI1, .config_func = config_func_1, }; static struct i2c_sam3_dev_data dev_data_1 = { .dev_config = CONFIG_I2C_1_DEFAULT_CFG, }; DEVICE_AND_API_INIT(i2c_sam3_1, CONFIG_I2C_1_NAME, &i2c_sam3_init, &dev_data_1, &dev_config_1, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &api_funcs); static void config_func_1(struct device *dev) { /* Enable clock for TWI0 controller */ PMC->PMC_PCER0 = (1 << ID_TWI1); IRQ_CONNECT(TWI1_IRQn, DT_I2C_1_IRQ_PRI, i2c_sam3_isr, DEVICE_GET(i2c_sam3_1), 0); irq_enable(TWI1_IRQn); } #endif /* CONFIG_I2C_1 */