int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { int status, count, errorResult; obj->i2c->ADDRESS = (address >> 1); obj->i2c->SHORTS = 1; // to trigger suspend task when a byte is received obj->i2c->EVENTS_RXDREADY = 0; obj->i2c->TASKS_STARTRX = 1; // Read in all except last byte for (count = 0; count < (length - 1); count++) { status = i2c_do_read(obj, &data[count], 0); if (status) { errorResult = checkError(obj); i2c_reset(obj); if (errorResult<0) { return errorResult; } return count; } } // read in last byte status = i2c_do_read(obj, &data[length - 1], 1); if (status) { i2c_reset(obj); return length - 1; } // If not repeated start, send stop. if (stop) { while (!obj->i2c->EVENTS_STOPPED) { } obj->i2c->EVENTS_STOPPED = 0; } return length; }
int i2c_byte_write(i2c_t *obj, int data) { int err; // clear all interrupts obj->i2c->intfl = 0x3FF; if (obj->start_pending) { obj->start_pending = 0; data = (data & 0xFF) | MXC_S_I2CM_TRANS_TAG_START; } else { data = (data & 0xFF) | MXC_S_I2CM_TRANS_TAG_TXDATA_ACK; } if ((err = write_tx_fifo(obj, data)) != 0) { return err; } obj->i2c->trans |= MXC_F_I2CM_TRANS_TX_START; // Wait for the FIFO to be empty while (!(obj->i2c->intfl & MXC_F_I2CM_INTFL_TX_FIFO_EMPTY)); if (obj->i2c->intfl & MXC_F_I2CM_INTFL_TX_NACKED) { i2c_reset(obj); return 0; } if (obj->i2c->intfl & (MXC_F_I2CM_INTFL_TX_TIMEOUT | MXC_F_I2CM_INTFL_TX_LOST_ARBITR)) { i2c_reset(obj); return 2; } return 1; }
/* * i2c_write: - Write multiple bytes to an i2c device * * The higher level routines take into account that this function is only * called with len < page length of the device (see configuration file) * * @chip: address of the chip which is to be written * @addr: i2c data address within the chip * @alen: length of the i2c data address (1..2 bytes) * @buffer: where to find the data to be written * @len: how much byte do we want to read * @return: 0 in case of success */ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) { struct mv_i2c_msg msg; u8 addr_bytes[3]; /* lowest...highest byte of data address */ PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, " "len=0x%02x)\n", chip, addr, alen, len)); i2c_reset(); /* chip address write */ PRINTD(("i2c_write: chip address write\n")); msg.condition = I2C_COND_START; msg.acknack = I2C_ACKNAK_WAITACK; msg.direction = I2C_WRITE; msg.data = (chip << 1); msg.data &= 0xFE; if (i2c_transfer(&msg)) return -1; /* * send memory address bytes; * alen defines how much bytes we have to send. */ addr_bytes[0] = (u8)((addr >> 0) & 0x000000FF); addr_bytes[1] = (u8)((addr >> 8) & 0x000000FF); addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF); while (--alen >= 0) { PRINTD(("i2c_write: send memory word address\n")); msg.condition = I2C_COND_NORMAL; msg.acknack = I2C_ACKNAK_WAITACK; msg.direction = I2C_WRITE; msg.data = addr_bytes[alen]; if (i2c_transfer(&msg)) return -1; } /* write bytes; send NACK at last byte */ while (len--) { PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n", (unsigned int)buffer, *buffer)); if (len == 0) msg.condition = I2C_COND_STOP; else msg.condition = I2C_COND_NORMAL; msg.acknack = I2C_ACKNAK_WAITACK; msg.direction = I2C_WRITE; msg.data = *(buffer++); if (i2c_transfer(&msg)) return -1; } i2c_reset(); return 0; }
void i2c_init(i2c_t *obj, PinName sda, PinName scl) { ret_code_t ret; int i; for (i = 0; i < TWI_COUNT; ++i) { if (m_twi_info[i].initialized && m_twi_info[i].pselsda == (uint32_t)sda && m_twi_info[i].pselscl == (uint32_t)scl) { TWI_IDX(obj) = i; TWI_INFO(obj)->frequency = NRF_TWI_FREQ_100K; i2c_reset(obj); return; } } for (i = 0; i < TWI_COUNT; ++i) { if (!m_twi_info[i].initialized) { ret = nrf_drv_common_per_res_acquire(m_twi_instances[i], m_twi_irq_handlers[i]); if (ret != NRF_SUCCESS) { continue; /* the hw resource is busy - test another one */ } TWI_IDX(obj) = i; twi_info_t *twi_info = TWI_INFO(obj); twi_info->initialized = true; twi_info->pselsda = (uint32_t)sda; twi_info->pselscl = (uint32_t)scl; twi_info->frequency = NRF_TWI_FREQ_100K; twi_info->start_twi = false; #if DEVICE_I2C_ASYNCH twi_info->active = false; #endif twi_clear_bus(twi_info); configure_twi_pin(twi_info->pselsda, NRF_GPIO_PIN_DIR_INPUT); configure_twi_pin(twi_info->pselscl, NRF_GPIO_PIN_DIR_INPUT); i2c_reset(obj); #if DEVICE_I2C_ASYNCH NVIC_SetVector(twi_handlers[i].IRQn, twi_handlers[i].vector); nrf_drv_common_irq_enable(twi_handlers[i].IRQn, TWI_IRQ_PRIORITY); #endif return; } } error("No available I2C peripheral\r\n"); }
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { int err, retval = 0; int i; if (!(obj->stop_pending) && (obj->i2c->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) { return 0; } // clear all interrupts obj->i2c->intfl = 0x3FF; // write the address to the fifo if ((err = write_tx_fifo(obj, (MXC_S_I2CM_TRANS_TAG_START | address))) != 0) { // start + addr (write) i2c_reset(obj); return err; } obj->start_pending = 0; // start the transaction obj->i2c->trans |= MXC_F_I2CM_TRANS_TX_START; // load as much of the cmd into the FIFO as possible for (i = 0; i < length; i++) { if ((err = write_tx_fifo(obj, (MXC_S_I2CM_TRANS_TAG_TXDATA_ACK | data[i]))) != 0) { // cmd (expect ACK) retval = (retval ? retval : err); break; } } if (stop) { obj->stop_pending = 0; if ((err = write_tx_fifo(obj, MXC_S_I2CM_TRANS_TAG_STOP)) != 0) { // stop condition retval = (retval ? retval : err); } if ((err = wait_tx_in_progress(obj)) != 0) { retval = (retval ? retval : err); } } else { obj->stop_pending = 1; int timeout = MXC_I2CM_TX_TIMEOUT; // Wait for TX fifo to be empty while (!(obj->i2c->intfl & MXC_F_I2CM_INTFL_TX_FIFO_EMPTY) && timeout--); } if (retval == 0) { return length; } i2c_reset(obj); return retval; }
/* Function to init EEPROM driver and I2C peripheral */ void eeprom_init(void) { /* Enable GPIOB clock. */ rcc_periph_clock_enable(RCC_GPIOB); /* set I2C1_SCL and I2C1_SDA, external pull-up resistors */ gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO6 | GPIO7); /* Open Drain, Speed 100 MHz */ gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_100MHZ, GPIO6 | GPIO7); /* Alternate Function: I2C1 */ gpio_set_af(GPIOB, GPIO_AF4, GPIO6 | GPIO7); /* Enable I2C1 clock. */ rcc_periph_clock_enable(RCC_I2C1); /* Enable I2C1 interrupt. */ nvic_enable_irq(NVIC_I2C1_EV_IRQ); /* reset I2C1 */ i2c_reset(I2C1); /* standard mode */ i2c_set_standard_mode(I2C1); /* clock and bus frequencies */ i2c_set_clock_frequency(I2C1, I2C_CR2_FREQ_2MHZ); i2c_set_ccr(I2C1, 20); /* enable error event interrupt only */ i2c_enable_interrupt(I2C1, I2C_CR2_ITERREN); /* enable I2C */ i2c_peripheral_enable(I2C1); }
/********************************************************************** name : function : return : 0 success, -1 no slave, -2 bus busy **********************************************************************/ int8_t TwoWire::endTransmission( uint8_t stop) { int8_t result=0; result = i2c_write(&i2c, Transfer_Addr, (const char *)TX_Buffer, TX_BufferHead, stop); TX_BufferHead = 0; twi_status = MASTER_IDLE; if(i2c.i2c->EVENTS_ERROR == 1) { if (i2c.i2c->ERRORSRC & TWI_ERRORSRC_ANACK_Msk) { i2c.i2c->EVENTS_ERROR = 0; i2c.i2c->TASKS_STOP = 1; result = I2C_ERROR_NO_SLAVE; } else if(i2c.i2c->ERRORSRC & TWI_ERRORSRC_DNACK_Msk) { i2c.i2c->EVENTS_ERROR = 0; i2c.i2c->TASKS_STOP = 1; result = I2C_ERROR_BUS_BUSY; } } if(stop) i2c_reset(&i2c); return result; }
irom static app_action_t application_function_i2c_write(application_parameters_t ap) { uint16_t src_current, dst_current; i2c_error_t error; uint8_t bytes[32]; for(src_current = 1, dst_current = 0; (src_current < ap.nargs) && (dst_current < sizeof(bytes)); src_current++, dst_current++) { bytes[dst_current] = (uint8_t)strtoul((*ap.args)[src_current], 0, 16); } if((error = i2c_send(i2c_address, dst_current, bytes)) != i2c_error_ok) { i2c_error_format_string("i2c-write", error, ap.size, ap.dst); strlcat(ap.dst, "\n", ap.size); i2c_reset(); return(app_action_error); } snprintf(ap.dst, ap.size, "i2c_write: written %u bytes to %02x\n", dst_current, i2c_address); return(app_action_normal); }
static void stmpe811_i2c_init() { rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_GPIOC); rcc_periph_clock_enable(RCC_I2C3); gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8); gpio_set_output_options(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO8); gpio_set_af(GPIOA, GPIO_AF4, GPIO8); gpio_mode_setup(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9); gpio_set_output_options(GPIOC, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO9); gpio_set_af(GPIOC, GPIO_AF4, GPIO9); i2c_peripheral_disable(I2C3); /* disable i2c during setup */ i2c_reset(I2C3); i2c_set_fast_mode(I2C3); i2c_set_clock_frequency(I2C3, I2C_CR2_FREQ_42MHZ); i2c_set_ccr(I2C3, 35); i2c_set_trise(I2C3, 43); i2c_peripheral_enable(I2C3); /* finally enable i2c */ i2c_set_own_7bit_slave_address(I2C3, 0x00); }
irom static app_action_t application_function_i2c_write(const string_t *src, string_t *dst) { i2c_error_t error; static uint8_t bytes[32]; int current, out; for(current = 0; current < (int)sizeof(bytes); current++) { if(parse_int(current + 1, src, &out, 16) != parse_ok) break; bytes[current] = (uint8_t)(out & 0xff); } if((error = i2c_send(i2c_address, current, bytes)) != i2c_error_ok) { string_cat(dst, "i2c_write"); i2c_error_format_string(dst, error); string_cat(dst, "\n"); i2c_reset(); return(app_action_error); } string_format(dst, "i2c_write: written %d bytes to %02x\n", current, i2c_address); return(app_action_normal); }
void i2c_init(i2c_t *obj, PinName sda, PinName scl) { // Determine the I2C to use I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl); MBED_ASSERT(obj->i2c != (I2CName)NC); // Enable I2C clock if (obj->i2c == I2C_1) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK); } if (obj->i2c == I2C_2) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); } // Configure I2C pins pinmap_pinout(scl, PinMap_I2C_SCL); pin_mode(scl, OpenDrain); pinmap_pinout(sda, PinMap_I2C_SDA); pin_mode(sda, OpenDrain); // Reset to clear pending flags if any i2c_reset(obj); // I2C configuration i2c_frequency(obj, 100000); // 100 kHz per default }
void cliFunc_ledReset( char* args ) { print( NL ); // No \r\n by default after the command is entered // Reset I2C bus #if ISSI_Chip_31FL3733_define == 1 || ISSI_Chip_31FL3736_define == 1 GPIO_Ctrl( iirst_pin, GPIO_Type_DriveSetup, GPIO_Config_Pullup ); GPIO_Ctrl( iirst_pin, GPIO_Type_DriveHigh, GPIO_Config_Pullup ); delay_us(50); GPIO_Ctrl( iirst_pin, GPIO_Type_DriveLow, GPIO_Config_Pullup ); #endif i2c_reset(); // Clear control registers LED_zeroControlPages(); // Clear buffers for ( uint8_t buf = 0; buf < ISSI_Chips_define; buf++ ) { memset( (void*)LED_pageBuffer[ buf ].buffer, 0, LED_BufferLength * 2 ); } // Reset LEDs LED_reset(); }
/* * Initializes I2C0 */ void i2c_init() { // Initialize DMA timer for use in transfer delays dtim0_init(); // Configure GPIO port AS for SCL and SDA MCF_GPIO_PASPAR |= MCF_GPIO_PASPAR_SCL0_SCL0; MCF_GPIO_PASPAR |= MCF_GPIO_PASPAR_SDA0_SDA0; // Do we need data direction as output? /*MCF_GPIO_DDRAS |= MCF_GPIO_DDRAS_DDRAS0; MCF_GPIO_DDRAS |= MCF_GPIO_DDRAS_DDRAS1;*/ // Write the I2C board address MCF_I2C0_I2ADR |= MCF_I2C_I2ADR_ADR(I2C_ADDR); // Write the i2c clock rate. f_i2c = 80Mhz / divider // divider = 80Mhz / 0.1 Mhz = 800. Closest divider in Table 29.2 896 for 89.29Khz, IC = 0x3A MCF_I2C0_I2FDR |= MCF_I2C_I2FDR_IC(0x3A); // Reset to slave-receiver mode i2c_reset(); // If the bus is busy b/c a slave is transmitting, generate a stop bit when switching // from master-recviver back to slave-receiver if(MCF_I2C0_I2SR & MCF_I2C_I2SR_IBB) { MCF_I2C0_I2CR = 0x00; // Board is slave-receiver, i2c disabled, interrupts disabled MCF_I2C0_I2CR = 0xA0; // Board is master-receiver, i2c enabled, interrupts, disabled uint8_t dummy = MCF_I2C0_I2DR; // Dummy read from slave which is transmitting MCF_I2C0_I2SR = 0x00; // Clear arbitration lost flag, clear i2c interrupt request flag MCF_I2C0_I2CR = 0x00; // Board is slave-receiver, i2c disabled, interrupts disabled MCF_I2C0_I2CR = 0x80; // Enable I2C module } }
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { int status, errorResult; obj->i2c->ADDRESS = (address >> 1); obj->i2c->SHORTS = 0; obj->i2c->TASKS_STARTTX = 1; for (int i = 0; i<length; i++) { status = i2c_do_write(obj, data[i]); if (status) { i2c_reset(obj); errorResult = checkError(obj); if (errorResult<0) { return errorResult; } return i; } } // If not repeated start, send stop. if (stop) { if (i2c_stop(obj)) { return I2C_ERROR_NO_SLAVE; } } return length; }
/** **************************************************************************************** * @brief Initializes the I2C controller * @param[in] buffer i2c buffer (point to a gobal memory) * @param[in] size i2c buffer len, = address size + data size * @description * The function is used to initialize I2C in slave mode, this function is also * used to enable I2c interrupt, and enable NVIC I2C IRQ. ***************************************************************************************** */ void i2c_init(uint8_t *buffer, uint16_t size) { uint32_t reg; i2c_env.i2cOpFsm = I2C_OP_IDLE; i2c_env.i2cBufferSize = size; i2c_env.i2cBuffer = buffer; i2c_reset(); #if CONFIG_I2C_ENABLE_INTERRUPT==TRUE /* Enable the I2C Interrupt */ NVIC_EnableIRQ(I2C_IRQn); #endif /* * Mask all slave interrupt in I2C component */ reg = I2C_SLAVE_ADDR(QN9020_I2C_ADDR) // slave address, slave mode active | I2C_MASK_SLAVE_EN // slave | I2C_MASK_STP_INT_EN // Enable abnormal stop interrupt | I2C_MASK_SAM_INT_EN // Enable slave address match interrupt, slave mode active | I2C_MASK_GC_INT_EN // Enable general call interrupt, slave mode active | I2C_MASK_RX_INT_EN // Enable RX interrupt | I2C_MASK_TX_INT_EN; // Enable TX interrupt i2c_i2c_SetCR(QN_I2C, reg); reg = I2C_MASK_RD_EN | I2C_MASK_SLV_ACK_SEND; //ACK i2c_i2c_SetTXD(QN_I2C, reg); }
int i2c_start(i2c_t *obj) { int status = 0; i2c_reset(obj); obj->address_set = 0; return status; }
void i2c_init(i2c_t *obj, PinName sda, PinName scl) { // Determine the I2C to use I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl); if (obj->i2c == (I2CName)NC) { error("I2C error: pinout mapping failed."); } // Enable I2C clock if (obj->i2c == I2C_1) { __HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_SYSCLK); __I2C1_CLK_ENABLE(); } if (obj->i2c == I2C_2) { __I2C2_CLK_ENABLE(); } // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); pin_mode(sda, OpenDrain); pin_mode(scl, OpenDrain); // Reset to clear pending flags if any i2c_reset(obj); // I2C configuration i2c_frequency(obj, 100000); // 100 kHz per default }
void i2c2_hw_init(void) { i2c2.reg_addr = (void *)I2C2; i2c2.init_struct = NULL; i2c2.errors = &i2c2_errors; i2c2_watchdog_counter = 0; /* zeros error counter */ ZEROS_ERR_COUNTER(i2c2_errors); /* reset peripheral to default state ( sometimes not achieved on reset :( ) */ //i2c_reset(I2C2); /* Configure priority grouping 0 bits for pre-emption priority and 4 bits for sub-priority. */ scb_set_priority_grouping(SCB_AIRCR_PRIGROUP_NOGROUP_SUB16); /* Configure and enable I2C2 event interrupt --------------------------------*/ nvic_set_priority(NVIC_I2C2_EV_IRQ, 0); nvic_enable_irq(NVIC_I2C2_EV_IRQ); /* Configure and enable I2C2 err interrupt ----------------------------------*/ nvic_set_priority(NVIC_I2C2_ER_IRQ, 1); nvic_enable_irq(NVIC_I2C2_ER_IRQ); /* Enable peripheral clocks -------------------------------------------------*/ /* Enable I2C2 clock */ rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_I2C2EN); /* Enable GPIO clock */ gpio_enable_clock(I2C2_GPIO_PORT); #if defined(STM32F1) gpio_set_mode(I2C2_GPIO_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, I2C2_GPIO_SCL | I2C2_GPIO_SDA); #elif defined(STM32F4) gpio_mode_setup(I2C2_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, I2C2_GPIO_SCL | I2C2_GPIO_SDA); gpio_set_output_options(I2C2_GPIO_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ, I2C2_GPIO_SCL | I2C2_GPIO_SDA); gpio_set_af(I2C2_GPIO_PORT, GPIO_AF4, I2C2_GPIO_SCL | I2C2_GPIO_SDA); #endif i2c_reset(I2C2); // enable peripheral i2c_peripheral_enable(I2C2); /* * XXX: there is a function to do that already in libopencm3 but I am not * sure if it is correct, using direct register instead (esden) */ //i2c_set_own_7bit_slave_address(I2C2, 0); I2C_OAR1(I2C2) = 0 | 0x4000; // enable error interrupts I2C_CR2(I2C1) |= I2C_CR2_ITERREN; i2c_setbitrate(&i2c2, I2C2_CLOCK_SPEED); }
void i2c_init(i2c_t *obj, PinName sda, PinName scl) { static int i2c1_inited = 0; static int i2c2_inited = 0; #if defined(I2C3_BASE) static int i2c3_inited = 0; #endif // Determine the I2C to use I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl); MBED_ASSERT(obj->i2c != (I2CName)NC); // Enable I2C1 clock and pinout if not done if ((obj->i2c == I2C_1) && !i2c1_inited) { i2c1_inited = 1; __HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_SYSCLK); __I2C1_CLK_ENABLE(); // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); pin_mode(sda, OpenDrain); pin_mode(scl, OpenDrain); } // Enable I2C2 clock and pinout if not done if ((obj->i2c == I2C_2) && !i2c2_inited) { i2c2_inited = 1; __I2C2_CLK_ENABLE(); // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); pin_mode(sda, OpenDrain); pin_mode(scl, OpenDrain); } #if defined(I2C3_BASE) // Enable I2C3 clock and pinout if not done if ((obj->i2c == I2C_3) && !i2c3_inited) { i2c3_inited = 1; __I2C3_CLK_ENABLE(); // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); pin_mode(sda, OpenDrain); pin_mode(scl, OpenDrain); } #endif // Reset to clear pending flags if any i2c_reset(obj); // I2C configuration i2c_frequency(obj, 100000); // 100 kHz per default }
irom i2c_error_t i2c_init(int sda_pin, int scl_pin, int i2c_delay) { sda_mask = 1 << sda_pin; scl_mask = 1 << scl_pin; transaction_bit_delay = i2c_delay; i2c_flags.init_done = 1; return(i2c_reset()); }
int i2c_byte_read(i2c_t *obj, int last) { char data; int status; status = i2c_do_read(obj, &data, last); if (status) { i2c_reset(obj); } return data; }
void i2c_recovery(int controller) { CPUTS("RECOVERY\r\n"); /* Abort data, generating STOP condition */ if (i2c_abort_data(controller) == 1 && i2c_stsobjs[controller].err_code == SMB_MASTER_NO_ADDRESS_MATCH) return; /* Reset i2c controller by re-enable i2c controller*/ i2c_reset(controller); }
void i2c3_hw_init(void) { i2c3.reg_addr = (void *)I2C3; i2c3.init_struct = NULL; i2c3.errors = &i2c3_errors; i2c3_watchdog_counter = 0; /* zeros error counter */ ZEROS_ERR_COUNTER(i2c3_errors); /* reset peripheral to default state ( sometimes not achieved on reset :( ) */ //i2c_reset(I2C3); /* Configure and enable I2C3 event interrupt --------------------------------*/ nvic_set_priority(NVIC_I2C3_EV_IRQ, NVIC_I2C3_IRQ_PRIO); nvic_enable_irq(NVIC_I2C3_EV_IRQ); /* Configure and enable I2C3 err interrupt ----------------------------------*/ nvic_set_priority(NVIC_I2C3_ER_IRQ, NVIC_I2C3_IRQ_PRIO+1); nvic_enable_irq(NVIC_I2C3_ER_IRQ); /* Enable peripheral clocks -------------------------------------------------*/ /* Enable I2C3 clock */ rcc_periph_clock_enable(RCC_I2C3); /* Enable GPIO clock */ gpio_enable_clock(I2C3_GPIO_PORT_SCL); gpio_mode_setup(I2C3_GPIO_PORT_SCL, GPIO_MODE_AF, GPIO_PUPD_NONE, I2C3_GPIO_SCL); gpio_set_output_options(I2C3_GPIO_PORT_SCL, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ, I2C3_GPIO_SCL); gpio_set_af(I2C3_GPIO_PORT_SCL, GPIO_AF4, I2C3_GPIO_SCL); gpio_enable_clock(I2C3_GPIO_PORT_SDA); gpio_mode_setup(I2C3_GPIO_PORT_SDA, GPIO_MODE_AF, GPIO_PUPD_NONE, I2C3_GPIO_SDA); gpio_set_output_options(I2C3_GPIO_PORT_SDA, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ, I2C3_GPIO_SDA); gpio_set_af(I2C3_GPIO_PORT_SDA, GPIO_AF4, I2C3_GPIO_SDA); i2c_reset(I2C3); // enable peripheral i2c_peripheral_enable(I2C3); /* * XXX: there is a function to do that already in libopencm3 but I am not * sure if it is correct, using direct register instead (esden) */ //i2c_set_own_7bit_slave_address(I2C3, 0); I2C_OAR1(I2C3) = 0 | 0x4000; // enable error interrupts I2C_CR2(I2C1) |= I2C_CR2_ITERREN; i2c_setbitrate(&i2c3, I2C3_CLOCK_SPEED); }
static int wait_tx_in_progress(i2c_t *obj) { int timeout = MXC_I2CM_TX_TIMEOUT; while ((obj->i2c->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS) && --timeout); uint32_t intfl = obj->i2c->intfl; if (intfl & MXC_F_I2CM_INTFL_TX_NACKED) { i2c_reset(obj); return I2C_ERROR_NO_SLAVE; } if (!timeout || (intfl & (MXC_F_I2CM_INTFL_TX_TIMEOUT | MXC_F_I2CM_INTFL_TX_LOST_ARBITR))) { i2c_reset(obj); return I2C_ERROR_BUS_BUSY; } return 0; }
int i2c_byte_read(i2c_t *obj, int last) { uint16_t fifo_value; int err; // clear all interrupts obj->i2c->intfl = 0x3FF; if (last) { fifo_value = MXC_S_I2CM_TRANS_TAG_RXDATA_NACK; } else { fifo_value = MXC_S_I2CM_TRANS_TAG_RXDATA_COUNT; } if ((err = write_tx_fifo(obj, fifo_value)) != 0) { i2c_reset(obj); return err; } obj->i2c->trans |= MXC_F_I2CM_TRANS_TX_START; int timeout = MXC_I2CM_RX_TIMEOUT; while (!(obj->i2c->intfl & MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY) && (!(obj->i2c->bb & MXC_F_I2CM_BB_RX_FIFO_CNT))) { if ((--timeout < 0) || (obj->i2c->trans & (MXC_F_I2CM_TRANS_TX_TIMEOUT | MXC_F_I2CM_TRANS_TX_LOST_ARBITR | MXC_F_I2CM_TRANS_TX_NACKED))) { break; } } if (obj->i2c->intfl & MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY) { obj->i2c->intfl = MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY; return *obj->fifos->rslts; } i2c_reset(obj); return -1; }
void i2c_init(i2c_t *obj, PinName sda, PinName scl) { // Determine the I2C to use I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl); MBED_ASSERT(obj->i2c != (I2CName)NC); // Enable I2C1 clock and pinout if not done if ((obj->i2c == I2C_1) && !i2c1_inited) { i2c1_inited = 1; __I2C1_CLK_ENABLE(); // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); pin_mode(sda, OpenDrain); pin_mode(scl, OpenDrain); } // Enable I2C2 clock and pinout if not done if ((obj->i2c == I2C_2) && !i2c2_inited) { i2c2_inited = 1; __I2C2_CLK_ENABLE(); // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); pin_mode(sda, OpenDrain); pin_mode(scl, OpenDrain); } // Enable I2C3 clock and pinout if not done if ((obj->i2c == I2C_3) && !i2c3_inited) { i2c3_inited = 1; __I2C3_CLK_ENABLE(); // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); pin_mode(sda, OpenDrain); pin_mode(scl, OpenDrain); } // Reset to clear pending flags if any i2c_reset(obj); // I2C configuration i2c_frequency(obj, 100000); // 100 kHz per default // I2C master by default obj->slave = 0; }
irom static app_action_t application_function_i2c_reset(application_parameters_t ap) { i2c_error_t error; if((error = i2c_reset()) != i2c_error_ok) { i2c_error_format_string("i2c-reset", error, ap.size, ap.dst); strlcat(ap.dst, "\n", ap.size); return(app_action_error); } snprintf(ap.dst, ap.size, "i2c_reset: ok\n"); return(app_action_normal); }
/*--------------------------------------------------------------------------------------------------------------------------------------------------- * Initializes the I2C hardware * @details Configures I2C bus in order to operate as I2C master * @return TRUE if successful, FALSE, if not *--------------------------------------------------------------------------------------------------------------------------------------------------- */ uint8_t i2c_master_init(void) { static uint8_t already_called; uint8_t rtc; if (!already_called) { rtc = i2c_reset(); // try to reset I2C bus TWSR = 0; // no prescaler TWBR = ((F_CPU / SCL_CLOCK) - 16) / 2; // must be > 10 for stable operation already_called = 1; } else { rtc = 0; } return rtc; }
irom static app_action_t application_function_i2c_read(const string_t *src, string_t *dst) { int size, current; i2c_error_t error; uint8_t bytes[32]; uint32_t start, stop, clocks, spent; if(parse_int(1, src, &size, 0) != parse_ok) { string_cat(dst, "i2c-read: missing byte count\n"); return(app_action_error); } if(size > (int)sizeof(bytes)) { string_format(dst, "i2c-read: read max %d bytes\n", sizeof(bytes)); return(app_action_error); } start = system_get_time(); if((error = i2c_receive(i2c_address, size, bytes)) != i2c_error_ok) { string_cat(dst, "i2c_read"); i2c_error_format_string(dst, error); string_cat(dst, "\n"); i2c_reset(); return(app_action_error); } stop = system_get_time(); string_format(dst, "> i2c_read: read %d bytes from %02x:", size, i2c_address); for(current = 0; current < size; current++) string_format(dst, " %02x", bytes[current]); string_cat(dst, "\n"); clocks = (size + 1) * 20U; spent = (stop - start) * 1000U; string_format(dst, "> transferred %u bytes in %u scl clocks\n", size + 1U, clocks); string_format(dst, "> time spent: %u microseconds, makes %u kHz i2c bus\n", spent / 1000U, 1000000U / (spent / clocks)); return(app_action_normal); }
irom static app_action_t application_function_i2c_reset(const string_t *src, string_t *dst) { i2c_error_t error; if((error = i2c_reset()) != i2c_error_ok) { string_cat(dst, "i2c-reset: "); i2c_error_format_string(dst, error); string_cat(dst, "\n"); return(app_action_error); } string_cat(dst, "i2c_reset: ok\n"); return(app_action_normal); }