Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
/*
 * 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;
}
Example #4
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");
}
Example #5
0
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;
}
Example #6
0
/* 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);
}
Example #7
0
/**********************************************************************
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);
}
Example #11
0
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
}
Example #12
0
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();
}
Example #13
0
/*
 * 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
	}
}
Example #14
0
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;
}
Example #15
0
/**
 ****************************************************************************************
 * @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);

}
Example #16
0
int i2c_start(i2c_t *obj)
{
    int status = 0;
    i2c_reset(obj);
    obj->address_set = 0;
    return status;
}
Example #17
0
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
}
Example #18
0
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);
}
Example #19
0
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());
}
Example #21
0
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;
}
Example #22
0
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);
}
Example #23
0
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);
}
Example #24
0
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;
}
Example #25
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;
}
Example #26
0
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);
}
Example #28
0
/*---------------------------------------------------------------------------------------------------------------------------------------------------
 *  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);
}