Example #1
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);
}
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);
}
static void i2c_setup(void)
{
	/* Enable clocks for I2C2 and AFIO. */
	rcc_periph_clock_enable(RCC_I2C2);
	rcc_periph_clock_enable(RCC_AFIO);

	/* Set alternate functions for the SCL and SDA pins of I2C2. */
	gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
		      GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN,
		      GPIO_I2C2_SCL | GPIO_I2C2_SDA);

	/* Disable the I2C before changing any configuration. */
	i2c_peripheral_disable(I2C2);

	/* APB1 is running at 36MHz. */
	i2c_set_clock_frequency(I2C2, I2C_CR2_FREQ_36MHZ);

	/* 400KHz - I2C Fast Mode */
	i2c_set_fast_mode(I2C2);

	/*
	 * fclock for I2C is 36MHz APB2 -> cycle time 28ns, low time at 400kHz
	 * incl trise -> Thigh = 1600ns; CCR = tlow/tcycle = 0x1C,9;
	 * Datasheet suggests 0x1e.
	 */
	i2c_set_ccr(I2C2, 0x1e);

	/*
	 * fclock for I2C is 36MHz -> cycle time 28ns, rise time for
	 * 400kHz => 300ns and 100kHz => 1000ns; 300ns/28ns = 10;
	 * Incremented by 1 -> 11.
	 */
	i2c_set_trise(I2C2, 0x0b);

	/*
	 * This is our slave address - needed only if we want to receive from
	 * other masters.
	 */
	i2c_set_own_7bit_slave_address(I2C2, 0x32);

	/* If everything is configured -> enable the peripheral. */
	i2c_peripheral_enable(I2C2);
}
Example #4
0
void tmp_peripheral_setup(void) {

    gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO6 | GPIO7);
    gpio_set_output_options(GPIOB,
            GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ, GPIO6 | GPIO7);

    // Set this manually due to a big in libopencm3
    /*gpio_set_af(GPIOB, GPIO_AF4, GPIO6 | GPIO7);*/
    GPIOB_AFRL = (4<<(6*4)) | (4<<(7*4));

    i2c_reset(I2C1);

    i2c_peripheral_disable(I2C1);
    i2c_set_clock_frequency(I2C1, I2C_CR2_FREQ_30MHZ);
    i2c_set_standard_mode(I2C1);
    i2c_set_ccr(I2C1, 1600);
    i2c_set_trise(I2C1, 0x10);

    i2c_peripheral_enable(I2C1);

}
Example #5
0
static void i2c_init(void)
{
    /* i2c control lines */
    rcc_periph_clock_enable(RCC_GPIOB);
    gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO6 | GPIO7);
    gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_100MHZ /* GPIO_OSPEED_2MHZ */, GPIO6 | GPIO7);
    gpio_set_af(GPIOB, GPIO_AF4, GPIO6 | GPIO7);


    rcc_periph_clock_enable(I2C_CLOCK);

    i2c_reset(I2C_PORT);
    i2c_peripheral_disable(I2C_PORT);

    i2c_set_standard_mode(I2C_PORT);
    i2c_enable_ack(I2C_PORT);
    i2c_set_dutycycle(I2C_PORT, I2C_CCR_DUTY_DIV2); /* default, no need to do this really */

    i2c_set_clock_frequency(I2C_PORT, I2C_FREQ);
    /* CCR is the number of APB bus cycles in *half* an I2C bus
     * cycle. For Sm (100Khz) this ends up as:
     *   freq * 1MHz / 2 * 100KHz
     *   freq * 1000000 / 200000
     *   freq * 5
     *
     * Similar trise is the number of APB bus cycles in the rise
     * time (plus 1). For Sm (1us) this ends up as:
     *   freq * 1Mhz / (1/1us)  + 1
     *   freq * 1MHz / 1MHz  + 1
     *   freq + 1
     */
    /* 42MHz / (100kHz * 2) */
    i2c_set_ccr(I2C_PORT, I2C_FREQ * 5);
    /* standard mode, freqMhz+1*/
    i2c_set_trise(I2C_PORT, I2C_FREQ + 1);
    i2c_set_own_7bit_slave_address(I2C_PORT, OWN_ADDRESS);

    i2c_peripheral_enable(I2C_PORT);
}
Example #6
0
void init_i2c(const i2c_config *ip)
{
    // Enable periph clock.
    // Configure GPIO.
    // Reset I²C.

    uint32_t base = ip->i_base_address;

    enum rcc_periph_clken clken;
    switch (base) {
    case I2C1:
        clken = RCC_I2C1;
        break;
    case I2C2:
        clken = RCC_I2C2;
        break;
    default:
        assert(false && "unknown I2C base address");
    }
    rcc_periph_clock_enable(clken);

    gpio_init_pins(ip->i_pins, (&ip->i_pins)[1] - ip->i_pins);

    uint32_t i2c_freq_mhz = rcc_apb1_frequency / 1000000;
    uint32_t ccr = rcc_apb1_frequency / I2C_BAUD / 2 + 1;
    if (ccr < 4)
        ccr = 4;

    i2c_peripheral_disable(base);
    i2c_set_clock_frequency(base, i2c_freq_mhz);
    i2c_set_trise(base, i2c_freq_mhz + 1);
    i2c_set_ccr(base, ccr);
    I2C_CR1(base) = 0;
    I2C_OAR1(base) = ip->i_own_address;
    i2c_peripheral_enable(base);
}
Example #7
0
void i2c_setbitrate(struct i2c_periph *periph, int bitrate)
{
  // If NOT Busy
  if (i2c_idle(periph))
  {
    volatile int devider;
    volatile int risetime;

    uint32_t i2c = (uint32_t) periph->reg_addr;

    /*****************************************************
    Bitrate:

    -CR2 + CCR + TRISE registers
    -only change when PE=0

    e.g.

    10kHz:  36MHz + Standard 0x708 + 0x25
    70kHz:  36MHz + Standard 0x101 +
    400kHz: 36MHz + Fast 0x1E      + 0xb

    // 1) Program peripheral input clock CR2: to get correct timings
    // 2) Configure clock control registers
    // 3) Configure rise time register
    ******************************************************/

    if (bitrate < 3000)
      bitrate = 3000;

    // rcc_ppre1_frequency is normally configured to max: 36MHz on F1 and 42MHz on F4
    // in fast mode: 2counts low 1 count high -> / 3:
    // in standard mode: 1 count low, 1 count high -> /2:
    devider = (rcc_ppre1_frequency/2000) / (bitrate/1000);

    // never allow faster than 600kbps
    if (devider < 20)
      devider = 20;

    // no overflow either
    if (devider >=4095)
      devider = 4095;

    // risetime can be up to 1/6th of the period
    risetime = 1000000 / (bitrate/1000) / 6 / 28;

    if (risetime < 10)
      risetime = 10;

    // more will overflow the register: for more you should lower the FREQ
    if (risetime >=31)
      risetime = 31;

    // we do not expect an interrupt as the interface should have been idle, but just in case...
    __disable_irq(); // this code is in user space:

    // CCR can only be written when PE is disabled
    // p731 note 5
    i2c_peripheral_disable(i2c);

    // 1)
#ifdef STM32F1
    i2c_set_clock_frequency(i2c, I2C_CR2_FREQ_36MHZ);
#else // STM32F4
    i2c_set_clock_frequency(i2c, I2C_CR2_FREQ_42MHZ);
#endif
    // 2)
    //i2c_set_fast_mode(i2c);
    i2c_set_ccr(i2c, devider);
    // 3)
    i2c_set_trise(i2c, risetime);

    // Re-Enable
    i2c_peripheral_enable(i2c);

    __enable_irq();

#ifdef I2C_DEBUG_LED
    __disable_irq(); // this code is in user space:

    LED2_ON();
    LED1_ON();
    LED2_OFF();
    LED1_OFF();
    LED2_ON();
    LED1_ON();
    LED2_OFF();
    LED1_OFF();

    __enable_irq();
#endif

  }
}
Example #8
0
static uint8_t
u8g_board_com_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
{

	switch (msg) {
	case U8G_COM_MSG_INIT:
		//debug("u8com: init");

		/* configure I2C */
		i2c_peripheral_disable(I2C1);
		i2c_set_clock_frequency(I2C1, I2C_CR2_FREQ_36MHZ);
		i2c_set_fast_mode(I2C1);
		i2c_set_ccr(I2C1, 0x1e);
		i2c_set_trise(I2C1, 0x0b);
		i2c_set_own_7bit_slave_address(I2C1, 0x32);	/* XXX do we really want to be here? */
		i2c_peripheral_enable(I2C1);

		break;

	case U8G_COM_MSG_STOP:
		i2c_peripheral_disable(I2C1);
		break;

	case U8G_COM_MSG_ADDRESS:
		/* force a new start on address change */
//		com_send_stop();

		/* select address for command vs. data */
		current_address = arg_val ? 0x36 : 0x3c;
		break;

	case U8G_COM_MSG_CHIP_SELECT:
		if (arg_val) {
			//debug("u8com: select");
			/* do nothing here */

		} else {
			//debug("u8com: deselect");
//			com_send_stop();
		}

		break;

	case U8G_COM_MSG_RESET:
		break;

	case U8G_COM_MSG_WRITE_BYTE:
		//debug("u8com: send 0x%02x", arg_val);
		com_send_data(arg_val);
		break;

	case U8G_COM_MSG_WRITE_SEQ:
	case U8G_COM_MSG_WRITE_SEQ_P:
		//debug("u8com: seq %d", arg_val);
		{
			uint8_t *ptr = (uint8_t *)arg_ptr;

			while (arg_val-- > 0) {
				//debug("u8com:   0x%02x", *ptr);
				com_send_data(*ptr++);
			}
		}
		break;
	}

	return 1;
}
Example #9
0
static void setup_i2c_port(enum I2C_FREQ I2C_speed)
{
	// Disable I2C if it happens to be enabled
	i2c_peripheral_disable(I2C_PORT);
	dma_channel_reset(I2C_TX_DMA, I2C_TX_DMA_CHANNEL);
	i2c_disable_interrupt(I2C_PORT, (I2C_CR2_ITEVTEN | I2C_CR2_ITERREN));
	DISABLE_I2C_INTERRUPT();
	reset_i2c_pins();

	// set: Source, Destination, and Amount (DMA channel must be disabled)
	dma_set_peripheral_address(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, (uint32_t)&I2C_DR(I2C_PORT));
	dma_set_memory_address(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, 0);
	dma_set_number_of_data(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, 0);
	// set the DMA Configuration (DMA_CCRx)
	//			 (BIT 14) mem2mem_mode disabled
	dma_set_priority(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, DMA_CCR_PL_HIGH); // (BIT 12:13)
	dma_set_memory_size(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, DMA_CCR_MSIZE_8BIT); // (BIT 10:11)
	dma_set_peripheral_size(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, DMA_CCR_PSIZE_8BIT); // (BIT 8:9)
	dma_enable_memory_increment_mode(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 7)
	dma_disable_peripheral_increment_mode(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 6)
	//			 (BIT 5) Circular mode is disabled
	dma_set_read_from_memory(I2C_TX_DMA, I2C_TX_DMA_CHANNEL);	// (BIT 4)
	dma_enable_transfer_error_interrupt(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 3)
	dma_disable_half_transfer_interrupt(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 2)
	dma_enable_transfer_complete_interrupt(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 1)

	// This is the slave address when not transmitting data
	i2c_set_own_7bit_slave_address(I2C_PORT, 0x32);
	// do not respond to the specified slave address
	i2c_disable_ack(I2C_PORT);
	// Use DMA to send I2C data
	i2c_enable_dma(I2C_PORT);
	// set which interrupts I2C uses
	i2c_enable_interrupt(I2C_PORT, (I2C_CR2_ITEVTEN | I2C_CR2_ITERREN));
	// APB1 is running at 36MHz = T(PCLK1) = 1/36000000 sec.
	i2c_set_clock_frequency(I2C_PORT, I2C_CR2_FREQ_36MHZ);
	// Set up the hardware for the particular speed
	switch (I2C_speed) {
		// Values found on Internet for the I2C standard
		//   STANDARD : SCL max rise time = 1000ns = 1000/1000000000 sec
		//       FAST : SCL max rise time =  300ns =  300/1000000000 sec
		// 
		// DATASHEET Function:
		//   TRISE = (T(MAX_SCL_RISE) / T(PCLK1)) + 1
		// 
		// DATASHEET Functions:
		//   STANDARD :      
		//     T(high) =      CCR * T(PCLK1)
		//     T(low)  =      CCR * T(PCLK1)
		//   FAST (DUTY=I2C_CCR_DUTY_DIV2)
		//     T(high) =      CCR * T(PCLK1)
		//     T(low)  =  2 * CCR * T(PCLK1)
		//   FAST (DUTY=I2C_CCR_DUTY_16_DIV_9)   [To reach 400KHz]
		//     T(high) =  9 * CCR * T(PCLK1)
		//     T(low)  = 16 * CCR * T(PCLK1)
		// 
		// I2C PERIOD:
		//   STANDARD
		//     PERIOD = T(high) + T(low) = (2 * CCR * T(PCLK1))
		//   FAST (DUTY=I2C_CCR_DUTY_DIV2)
		//     PERIOD = T(high) + T(low) = (3 * CCR * T(PCLK1))
		//   FAST (DUTY=I2C_CCR_DUTY_16_DIV_9)
		//     PERIOD = T(high) + T(low) = (25 * CCR * T(PCLK1))
		case I2C_400KHz:
			// I2C PERIOD: 400KHz = 400000Hz = 1/400000 sec.
			i2c_set_fast_mode(I2C_PORT);
			// I2C_CCR_DUTY_DIV2 or I2C_CCR_DUTY_16_DIV_9
			i2c_set_dutycycle(I2C_PORT, I2C_CCR_DUTY_16_DIV_9);
			// CCR = PERIOD / (25 * T(PCLK1))
			// CCR = (1/400000) / (25/36000000) = 18/5 = 3.6
			// CCR = 4 => I2C PERIOD = 360kHz
			// CCR = 3 => I2C PERIOD = 480kHz
			i2c_set_ccr(I2C_PORT, 4);	// Only fast mode can have a value less than 0x04
			// TRISE = ( (300/1000000000) / (1/36000000) ) + 1 = 59/5 = 11.8
			// TRISE = 12 => SCL max rise time ~= 305.555ns
			// TRISE = 11 => SCL max rise time ~= 277.777ns
			i2c_set_trise(I2C_PORT, 11);
			break;
		case I2C_100KHz:
			// I2C PERIOD: 100KHz = 100000Hz = 1/100000 sec.
			i2c_set_standard_mode(I2C_PORT);
			// I2C_CCR_DUTY_DIV2 or I2C_CCR_DUTY_16_DIV_9
			i2c_set_dutycycle(I2C_PORT, I2C_CCR_DUTY_DIV2);
			// CCR = PERIOD / (2 * T(PCLK1))
			// CCR = (1/100000) / (2/36000000) = 180
			i2c_set_ccr(I2C_PORT, 180);
			// TRISE = ( (1000/1000000000) / (1/36000000) ) + 1 = 37
			i2c_set_trise(I2C_PORT, 37);
			break;
		case I2C_53KHz:
			// ~= 52.91kHz is the slowest I could get to work
			// CCR value of 341 works but not 342 or higher
		case I2C_50KHz:
		default:
			// I2C PERIOD: 50KHz = 50000Hz = 1/50000 sec.
			i2c_set_standard_mode(I2C_PORT);
			// I2C_CCR_DUTY_DIV2 or I2C_CCR_DUTY_16_DIV_9
			i2c_set_dutycycle(I2C_PORT, I2C_CCR_DUTY_DIV2);
			// CCR = PERIOD / (2 * T(PCLK1))
			// CCR = (1/50000) / (2/36000000) = 360
			//   (341 works but not 342 or higher)
			i2c_set_ccr(I2C_PORT, 341);
			// TRISE = ( (1000/1000000000) / (1/36000000) ) + 1 = 37
			i2c_set_trise(I2C_PORT, 37);
			break;
	}
	i2c_peripheral_enable(I2C_PORT);

	// set the priorities for the interrupts
	nvic_set_priority(I2C_EV_IRQ, IRQ_PRI_I2C);
	nvic_set_priority(I2C_ER_IRQ, IRQ_PRI_ER_I2C);
	nvic_set_priority(I2C_DMA_IRQ, IRQ_PRI_DMA_I2C);
}
static void setup_stm32f1_peripherals(void)
{
	rcc_peripheral_enable_clock(&RCC_APB1ENR, 
			RCC_APB1ENR_I2C1EN);

	rcc_peripheral_enable_clock(&RCC_APB2ENR, 
			RCC_APB2ENR_ADC1EN);

	/* GPIO pin for I2C1 SCL, SDA */

	/* VESNA v1.0
	gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
			GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO6);
	gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
			GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO7);
	*/

	/* VESNA v1.1 */
	AFIO_MAPR |= AFIO_MAPR_I2C1_REMAP;
	gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
			GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, TDA_PIN_SCL);
	gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
			GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, TDA_PIN_SDA);

	/* GPIO pin for TDA18219 IRQ */
	gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
			GPIO_CNF_INPUT_FLOAT, TDA_PIN_IRQ);

	/* GPIO pin for TDA18219 IF AGC */
	gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
			GPIO_CNF_OUTPUT_PUSHPULL, TDA_PIN_IF_AGC);
	/* Set to lowest gain for now */
	gpio_clear(GPIOA, TDA_PIN_IF_AGC);

	/* GPIO pin for AD8307 ENB */
	gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
			GPIO_CNF_OUTPUT_PUSHPULL, TDA_PIN_ENB);

	/* ADC pin for AD8307 output */
	gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
			GPIO_CNF_INPUT_ANALOG, TDA_PIN_OUT);

	/* Setup I2C */
	i2c_peripheral_disable(I2C1);

	/* 400 kHz - I2C Fast Mode */
	i2c_set_clock_frequency(I2C1, I2C_CR2_FREQ_24MHZ);
	i2c_set_fast_mode(I2C1);
	/* 400 kHz */
	i2c_set_ccr(I2C1, 0x14);
	/* 300 ns rise time */
	i2c_set_trise(I2C1, 0x08);

	i2c_peripheral_enable(I2C1);


	/* Make sure the ADC doesn't run during config. */
	adc_off(ADC1);

	/* We configure everything for one single conversion. */
	adc_disable_scan_mode(ADC1);
	adc_set_single_conversion_mode(ADC1);
	adc_enable_discontinous_mode_regular(ADC1);
	adc_disable_external_trigger_regular(ADC1);
	adc_set_right_aligned(ADC1);
	adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC);

	adc_on(ADC1);

	/* Wait for ADC starting up. */
	int i;
	for (i = 0; i < 800000; i++)    /* Wait a bit. */
		__asm__("nop");

	adc_reset_calibration(ADC1);
	adc_calibration(ADC1);

	uint8_t channel_array[16];
	/* Select the channel we want to convert. */
	if(TDA_PIN_OUT == GPIO0) {
		channel_array[0] = 0;
	} else if(TDA_PIN_OUT == GPIO2) {
		channel_array[0] = 2;
	}
	adc_set_regular_sequence(ADC1, 1, channel_array);
}